From f54f9f977ec2143028c6068ac43bff5da4bea2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 14 Nov 2020 18:52:56 +0200 Subject: [PATCH] audio: Update for subclassing API changes --- .../src/{audioecho.rs => audioecho/imp.rs} | 103 ++---------------- audio/audiofx/src/audioecho/mod.rs | 28 +++++ audio/audiofx/src/audioecho/ring_buffer.rs | 84 ++++++++++++++ .../imp.rs} | 79 +++++++------- audio/audiofx/src/audioloudnorm/mod.rs | 39 +++++++ .../{audiornnoise.rs => audiornnoise/imp.rs} | 28 ++--- audio/audiofx/src/audiornnoise/mod.rs | 28 +++++ audio/audiofx/src/lib.rs | 3 +- .../src/{claxondec.rs => claxondec/imp.rs} | 30 ++--- audio/claxon/src/claxondec/mod.rs | 27 +++++ audio/csound/src/{filter.rs => filter/imp.rs} | 37 +++---- audio/csound/src/filter/mod.rs | 37 +++++++ .../src/{lewtondec.rs => lewtondec/imp.rs} | 34 ++---- audio/lewton/src/lewtondec/mod.rs | 27 +++++ 14 files changed, 366 insertions(+), 218 deletions(-) rename audio/audiofx/src/{audioecho.rs => audioecho/imp.rs} (78%) create mode 100644 audio/audiofx/src/audioecho/mod.rs create mode 100644 audio/audiofx/src/audioecho/ring_buffer.rs rename audio/audiofx/src/{audioloudnorm.rs => audioloudnorm/imp.rs} (97%) create mode 100644 audio/audiofx/src/audioloudnorm/mod.rs rename audio/audiofx/src/{audiornnoise.rs => audiornnoise/imp.rs} (94%) create mode 100644 audio/audiofx/src/audiornnoise/mod.rs rename audio/claxon/src/{claxondec.rs => claxondec/imp.rs} (95%) create mode 100644 audio/claxon/src/claxondec/mod.rs rename audio/csound/src/{filter.rs => filter/imp.rs} (95%) create mode 100644 audio/csound/src/filter/mod.rs rename audio/lewton/src/{lewtondec.rs => lewtondec/imp.rs} (96%) create mode 100644 audio/lewton/src/lewtondec/mod.rs diff --git a/audio/audiofx/src/audioecho.rs b/audio/audiofx/src/audioecho/imp.rs similarity index 78% rename from audio/audiofx/src/audioecho.rs rename to audio/audiofx/src/audioecho/imp.rs index d2e1aedc..a374a91f 100644 --- a/audio/audiofx/src/audioecho.rs +++ b/audio/audiofx/src/audioecho/imp.rs @@ -13,7 +13,7 @@ use gst::subclass::prelude::*; use gst_base::subclass::prelude::*; use std::sync::Mutex; -use std::{cmp, i32, iter, u64}; +use std::{cmp, i32, u64}; use byte_slice_cast::*; @@ -28,6 +28,8 @@ lazy_static! { ); } +use super::ring_buffer::RingBuffer; + const DEFAULT_MAX_DELAY: u64 = gst::SECOND_VAL; const DEFAULT_DELAY: u64 = 500 * gst::MSECOND_VAL; const DEFAULT_INTENSITY: f64 = 0.5; @@ -57,7 +59,7 @@ struct State { buffer: RingBuffer, } -struct AudioEcho { +pub struct AudioEcho { settings: Mutex, state: Mutex>, } @@ -129,6 +131,7 @@ impl AudioEcho { impl ObjectSubclass for AudioEcho { const NAME: &'static str = "RsAudioEcho"; + type Type = super::AudioEcho; type ParentType = gst_base::BaseTransform; type Instance = gst::subclass::ElementInstanceStruct; type Class = subclass::simple::ClassStruct; @@ -142,7 +145,7 @@ impl ObjectSubclass for AudioEcho { } } - fn class_init(klass: &mut subclass::simple::ClassStruct) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Audio echo", "Filter/Effect/Audio", @@ -194,7 +197,7 @@ impl ObjectSubclass for AudioEcho { } impl ObjectImpl for AudioEcho { - fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) { + fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) { let prop = &PROPERTIES[id]; match *prop { @@ -220,7 +223,7 @@ impl ObjectImpl for AudioEcho { } } - fn get_property(&self, _obj: &glib::Object, id: usize) -> Result { + fn get_property(&self, _obj: &Self::Type, id: usize) -> Result { let prop = &PROPERTIES[id]; match *prop { @@ -250,7 +253,7 @@ impl ElementImpl for AudioEcho {} impl BaseTransformImpl for AudioEcho { fn transform_ip( &self, - _element: &gst_base::BaseTransform, + _element: &Self::Type, buf: &mut gst::BufferRef, ) -> Result { let mut settings = *self.settings.lock().unwrap(); @@ -278,7 +281,7 @@ impl BaseTransformImpl for AudioEcho { fn set_caps( &self, - _element: &gst_base::BaseTransform, + _element: &Self::Type, incaps: &gst::Caps, outcaps: &gst::Caps, ) -> Result<(), gst::LoggableError> { @@ -303,94 +306,10 @@ impl BaseTransformImpl for AudioEcho { Ok(()) } - fn stop(&self, _element: &gst_base::BaseTransform) -> Result<(), gst::ErrorMessage> { + fn stop(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { // Drop state let _ = self.state.lock().unwrap().take(); Ok(()) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "rsaudioecho", - gst::Rank::None, - AudioEcho::get_type(), - ) -} - -struct RingBuffer { - buffer: Box<[f64]>, - pos: usize, -} - -impl RingBuffer { - fn new(size: usize) -> Self { - let mut buffer = Vec::with_capacity(size as usize); - buffer.extend(iter::repeat(0.0).take(size as usize)); - - Self { - buffer: buffer.into_boxed_slice(), - pos: 0, - } - } - - fn iter(&mut self, delay: usize) -> RingBufferIter { - RingBufferIter::new(self, delay) - } -} - -struct RingBufferIter<'a> { - buffer: &'a mut [f64], - buffer_pos: &'a mut usize, - read_pos: usize, - write_pos: usize, -} - -impl<'a> RingBufferIter<'a> { - fn new(buffer: &'a mut RingBuffer, delay: usize) -> RingBufferIter<'a> { - let size = buffer.buffer.len(); - - assert!(size >= delay); - assert_ne!(size, 0); - - let read_pos = (size - delay + buffer.pos) % size; - let write_pos = buffer.pos % size; - - let buffer_pos = &mut buffer.pos; - let buffer = &mut buffer.buffer; - - RingBufferIter { - buffer, - buffer_pos, - read_pos, - write_pos, - } - } -} - -impl<'a> Iterator for RingBufferIter<'a> { - type Item = (&'a mut f64, f64); - - fn next(&mut self) -> Option { - let res = unsafe { - let r = *self.buffer.get_unchecked(self.read_pos); - let w = self.buffer.get_unchecked_mut(self.write_pos); - // Cast needed to get from &mut f64 to &'a mut f64 - (&mut *(w as *mut f64), r) - }; - - let size = self.buffer.len(); - self.write_pos = (self.write_pos + 1) % size; - self.read_pos = (self.read_pos + 1) % size; - - Some(res) - } -} - -impl<'a> Drop for RingBufferIter<'a> { - fn drop(&mut self) { - *self.buffer_pos = self.write_pos; - } -} diff --git a/audio/audiofx/src/audioecho/mod.rs b/audio/audiofx/src/audioecho/mod.rs new file mode 100644 index 00000000..0b9eb717 --- /dev/null +++ b/audio/audiofx/src/audioecho/mod.rs @@ -0,0 +1,28 @@ +// Copyright (C) 2017,2018 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use glib::prelude::*; + +mod imp; +mod ring_buffer; + +glib_wrapper! { + pub struct AudioEcho(ObjectSubclass) @extends gst_base::BaseTransform, gst::Element, gst::Object; +} + +unsafe impl Send for AudioEcho {} +unsafe impl Sync for AudioEcho {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "rsaudioecho", + gst::Rank::None, + AudioEcho::static_type(), + ) +} diff --git a/audio/audiofx/src/audioecho/ring_buffer.rs b/audio/audiofx/src/audioecho/ring_buffer.rs new file mode 100644 index 00000000..5eafefdd --- /dev/null +++ b/audio/audiofx/src/audioecho/ring_buffer.rs @@ -0,0 +1,84 @@ +// Copyright (C) 2017,2018 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::iter; + +pub struct RingBuffer { + buffer: Box<[f64]>, + pos: usize, +} + +impl RingBuffer { + pub fn new(size: usize) -> Self { + let mut buffer = Vec::with_capacity(size as usize); + buffer.extend(iter::repeat(0.0).take(size as usize)); + + Self { + buffer: buffer.into_boxed_slice(), + pos: 0, + } + } + + pub fn iter(&mut self, delay: usize) -> RingBufferIter { + RingBufferIter::new(self, delay) + } +} + +pub struct RingBufferIter<'a> { + buffer: &'a mut [f64], + buffer_pos: &'a mut usize, + read_pos: usize, + write_pos: usize, +} + +impl<'a> RingBufferIter<'a> { + fn new(buffer: &'a mut RingBuffer, delay: usize) -> RingBufferIter<'a> { + let size = buffer.buffer.len(); + + assert!(size >= delay); + assert_ne!(size, 0); + + let read_pos = (size - delay + buffer.pos) % size; + let write_pos = buffer.pos % size; + + let buffer_pos = &mut buffer.pos; + let buffer = &mut buffer.buffer; + + RingBufferIter { + buffer, + buffer_pos, + read_pos, + write_pos, + } + } +} + +impl<'a> Iterator for RingBufferIter<'a> { + type Item = (&'a mut f64, f64); + + fn next(&mut self) -> Option { + let res = unsafe { + let r = *self.buffer.get_unchecked(self.read_pos); + let w = self.buffer.get_unchecked_mut(self.write_pos); + // Cast needed to get from &mut f64 to &'a mut f64 + (&mut *(w as *mut f64), r) + }; + + let size = self.buffer.len(); + self.write_pos = (self.write_pos + 1) % size; + self.read_pos = (self.read_pos + 1) % size; + + Some(res) + } +} + +impl<'a> Drop for RingBufferIter<'a> { + fn drop(&mut self) { + *self.buffer_pos = self.write_pos; + } +} diff --git a/audio/audiofx/src/audioloudnorm.rs b/audio/audiofx/src/audioloudnorm/imp.rs similarity index 97% rename from audio/audiofx/src/audioloudnorm.rs rename to audio/audiofx/src/audioloudnorm/imp.rs index bc7194e9..25d9f69e 100644 --- a/audio/audiofx/src/audioloudnorm.rs +++ b/audio/audiofx/src/audioloudnorm/imp.rs @@ -201,7 +201,7 @@ impl State { } } -struct AudioLoudNorm { +pub struct AudioLoudNorm { srcpad: gst::Pad, sinkpad: gst::Pad, settings: Mutex, @@ -268,7 +268,7 @@ impl State { // Drains all full frames that are currently in the adapter fn drain_full_frames( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, ) -> Result, gst::FlowError> { let mut outbufs = vec![]; while self.adapter.available() >= self.info.bpf() as usize * self.current_samples_per_frame @@ -308,7 +308,7 @@ impl State { } // Drains everything - fn drain(&mut self, element: &gst::Element) -> Result { + fn drain(&mut self, element: &super::AudioLoudNorm) -> Result { gst_debug!(CAT, obj: element, "Draining"); let (pts, distance) = self.adapter.prev_pts(); @@ -363,7 +363,7 @@ impl State { fn process_first_frame_is_last( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, ) -> Result<(), gst::FlowError> { // Calculated loudness in LUFS let global = self @@ -411,7 +411,7 @@ impl State { fn process_first_frame( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, src: &[f64], pts: gst::ClockTime, ) -> Result<(gst::Buffer, gst::ClockTime), gst::FlowError> { @@ -485,7 +485,7 @@ impl State { Ok((outbuf, pts)) } - fn process_fill_inner_frame(&mut self, element: &gst::Element, src: &[f64]) { + fn process_fill_inner_frame(&mut self, element: &super::AudioLoudNorm, src: &[f64]) { // Get gain for this and the next 100ms frame based the delta array // and smoothened with a gaussian filter. let gain = self.gaussian_filter(if self.index + 10 < 30 { @@ -557,7 +557,7 @@ impl State { fn process_update_gain_inner_frame( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, ) -> Result<(), gst::FlowError> { // Calculate global, shortterm loudness and relative threshold in LUFS. let global = self @@ -641,7 +641,7 @@ impl State { fn process_inner_frame( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, src: &[f64], pts: gst::ClockTime, ) -> Result<(gst::Buffer, gst::ClockTime), gst::FlowError> { @@ -681,7 +681,7 @@ impl State { fn process_fill_final_frame( &mut self, - _element: &gst::Element, + _element: &super::AudioLoudNorm, idx: usize, num_samples: usize, ) { @@ -734,7 +734,7 @@ impl State { fn process_final_frame( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, src: &[f64], pts: gst::ClockTime, ) -> Result<(gst::Buffer, gst::ClockTime), gst::FlowError> { @@ -818,7 +818,7 @@ impl State { fn process_linear_frame( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, src: &[f64], pts: gst::ClockTime, ) -> Result<(gst::Buffer, gst::ClockTime), gst::FlowError> { @@ -855,7 +855,7 @@ impl State { fn process( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, src: &[f64], pts: gst::ClockTime, ) -> Result<(gst::Buffer, gst::ClockTime), gst::FlowError> { @@ -882,7 +882,7 @@ impl State { fn true_peak_limiter_out( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, mut smp_cnt: usize, nb_samples: usize, ) -> usize { @@ -923,7 +923,7 @@ impl State { fn true_peak_limiter_attack( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, mut smp_cnt: usize, nb_samples: usize, ) -> usize { @@ -1136,7 +1136,7 @@ impl State { fn true_peak_limiter_sustain( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, mut smp_cnt: usize, nb_samples: usize, ) -> usize { @@ -1252,7 +1252,7 @@ impl State { fn true_peak_limiter_release( &mut self, - element: &gst::Element, + element: &super::AudioLoudNorm, mut smp_cnt: usize, nb_samples: usize, ) -> usize { @@ -1371,7 +1371,7 @@ impl State { smp_cnt } - fn true_peak_limiter_first_frame(&mut self, element: &gst::Element) { + fn true_peak_limiter_first_frame(&mut self, element: &super::AudioLoudNorm) { let channels = self.info.channels() as usize; assert_eq!(self.limiter_buf_index, 0); @@ -1412,7 +1412,7 @@ impl State { } } - fn true_peak_limiter(&mut self, element: &gst::Element, dst: &mut [f64]) { + fn true_peak_limiter(&mut self, element: &super::AudioLoudNorm, dst: &mut [f64]) { let channels = self.info.channels() as usize; let nb_samples = dst.len() / channels; @@ -1588,7 +1588,7 @@ impl AudioLoudNorm { fn sink_chain( &self, _pad: &gst::Pad, - element: &gst::Element, + element: &super::AudioLoudNorm, buffer: gst::Buffer, ) -> Result { gst_log!(CAT, obj: element, "Handling buffer {:?}", buffer); @@ -1629,7 +1629,12 @@ impl AudioLoudNorm { Ok(gst::FlowSuccess::Ok) } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event( + &self, + pad: &gst::Pad, + element: &super::AudioLoudNorm, + event: gst::Event, + ) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -1712,7 +1717,12 @@ impl AudioLoudNorm { pad.event_default(Some(element), event) } - fn src_query(&self, pad: &gst::Pad, element: &gst::Element, query: &mut gst::QueryRef) -> bool { + fn src_query( + &self, + pad: &gst::Pad, + element: &super::AudioLoudNorm, + query: &mut gst::QueryRef, + ) -> bool { use gst::QueryView; gst_log!(CAT, obj: pad, "Handling query {:?}", query); @@ -1738,13 +1748,14 @@ impl AudioLoudNorm { impl ObjectSubclass for AudioLoudNorm { const NAME: &'static str = "RsAudioLoudNorm"; + type Type = super::AudioLoudNorm; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct; type Class = subclass::simple::ClassStruct; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .chain_function(|pad, parent, buffer| { @@ -1784,7 +1795,7 @@ impl ObjectSubclass for AudioLoudNorm { } } - fn class_init(klass: &mut subclass::simple::ClassStruct) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Audio loudness normalizer", "Filter/Effect/Audio", @@ -1824,15 +1835,14 @@ impl ObjectSubclass for AudioLoudNorm { } impl ObjectImpl for AudioLoudNorm { - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } - fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) { + fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) { let prop = &PROPERTIES[id]; match *prop { @@ -1856,7 +1866,7 @@ impl ObjectImpl for AudioLoudNorm { } } - fn get_property(&self, _obj: &glib::Object, id: usize) -> Result { + fn get_property(&self, _obj: &Self::Type, id: usize) -> Result { let prop = &PROPERTIES[id]; match *prop { @@ -1884,7 +1894,7 @@ impl ObjectImpl for AudioLoudNorm { impl ElementImpl for AudioLoudNorm { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result { let res = self.parent_change_state(element, transition); @@ -1901,15 +1911,6 @@ impl ElementImpl for AudioLoudNorm { } } -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "rsaudioloudnorm", - gst::Rank::None, - AudioLoudNorm::get_type(), - ) -} - fn init_gaussian_filter() -> [f64; 21] { let mut weights = [0.0f64; 21]; let mut total_weight = 0.0f64; diff --git a/audio/audiofx/src/audioloudnorm/mod.rs b/audio/audiofx/src/audioloudnorm/mod.rs new file mode 100644 index 00000000..54d0819f --- /dev/null +++ b/audio/audiofx/src/audioloudnorm/mod.rs @@ -0,0 +1,39 @@ +// Copyright (C) 2019-2020 Sebastian Dröge +// +// Audio processing part of this file ported from ffmpeg/libavfilter/af_loudnorm.c +// +// Copyright (c) 2016 Kyle Swanson +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// FFmpeg is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with FFmpeg; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct AudioLoudNorm(ObjectSubclass) @extends gst::Element, gst::Object; +} + +unsafe impl Send for AudioLoudNorm {} +unsafe impl Sync for AudioLoudNorm {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "rsaudioloudnorm", + gst::Rank::None, + AudioLoudNorm::static_type(), + ) +} diff --git a/audio/audiofx/src/audiornnoise.rs b/audio/audiofx/src/audiornnoise/imp.rs similarity index 94% rename from audio/audiofx/src/audiornnoise.rs rename to audio/audiofx/src/audiornnoise/imp.rs index 1d8f2208..521b7ba1 100644 --- a/audio/audiofx/src/audiornnoise.rs +++ b/audio/audiofx/src/audiornnoise/imp.rs @@ -40,7 +40,7 @@ struct State { adapter: gst_base::UniqueAdapter, } -struct AudioRNNoise { +pub struct AudioRNNoise { state: Mutex>, } @@ -111,7 +111,7 @@ impl State { } impl AudioRNNoise { - fn drain(&self, element: &gst_base::BaseTransform) -> Result { + fn drain(&self, element: &super::AudioRNNoise) -> Result { let mut state_lock = self.state.lock().unwrap(); let state = state_lock.as_mut().unwrap(); @@ -154,7 +154,7 @@ impl AudioRNNoise { fn generate_output( &self, - _element: &gst_base::BaseTransform, + _element: &super::AudioRNNoise, state: &mut State, ) -> Result { let available = state.adapter.available(); @@ -189,6 +189,7 @@ impl AudioRNNoise { impl ObjectSubclass for AudioRNNoise { const NAME: &'static str = "AudioRNNoise"; + type Type = super::AudioRNNoise; type ParentType = gst_base::BaseTransform; type Instance = gst::subclass::ElementInstanceStruct; type Class = subclass::simple::ClassStruct; @@ -201,7 +202,7 @@ impl ObjectSubclass for AudioRNNoise { } } - fn class_init(klass: &mut subclass::simple::ClassStruct) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Audio denoise", "Filter/Effect/Audio", @@ -250,7 +251,7 @@ impl ElementImpl for AudioRNNoise {} impl BaseTransformImpl for AudioRNNoise { fn set_caps( &self, - element: &gst_base::BaseTransform, + element: &Self::Type, incaps: &gst::Caps, outcaps: &gst::Caps, ) -> Result<(), gst::LoggableError> { @@ -293,7 +294,7 @@ impl BaseTransformImpl for AudioRNNoise { fn generate_output( &self, - element: &gst_base::BaseTransform, + element: &Self::Type, ) -> Result { // 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 @@ -321,7 +322,7 @@ impl BaseTransformImpl for AudioRNNoise { Ok(GenerateOutputSuccess::NoOutput) } - fn sink_event(&self, element: &gst_base::BaseTransform, event: gst::Event) -> bool { + fn sink_event(&self, element: &Self::Type, event: gst::Event) -> bool { use gst::EventView; if let EventView::Eos(_) = event.view() { @@ -335,7 +336,7 @@ impl BaseTransformImpl for AudioRNNoise { fn query( &self, - element: &gst_base::BaseTransform, + element: &Self::Type, direction: gst::PadDirection, query: &mut gst::QueryRef, ) -> bool { @@ -364,19 +365,10 @@ impl BaseTransformImpl for AudioRNNoise { BaseTransformImplExt::parent_query(self, element, direction, query) } - fn stop(&self, _element: &gst_base::BaseTransform) -> Result<(), gst::ErrorMessage> { + fn stop(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { // Drop state let _ = self.state.lock().unwrap().take(); Ok(()) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "audiornnoise", - gst::Rank::None, - AudioRNNoise::get_type(), - ) -} diff --git a/audio/audiofx/src/audiornnoise/mod.rs b/audio/audiofx/src/audiornnoise/mod.rs new file mode 100644 index 00000000..a7281de5 --- /dev/null +++ b/audio/audiofx/src/audiornnoise/mod.rs @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Philippe Normand +// Copyright (C) 2020 Natanael Mojica +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct AudioRNNoise(ObjectSubclass) @extends gst_base::BaseTransform, gst::Element, gst::Object; +} + +unsafe impl Send for AudioRNNoise {} +unsafe impl Sync for AudioRNNoise {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "audiornnoise", + gst::Rank::None, + AudioRNNoise::static_type(), + ) +} diff --git a/audio/audiofx/src/lib.rs b/audio/audiofx/src/lib.rs index a47062c4..aee83f0d 100644 --- a/audio/audiofx/src/lib.rs +++ b/audio/audiofx/src/lib.rs @@ -24,8 +24,9 @@ mod audiornnoise; fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { audioecho::register(plugin)?; + audioloudnorm::register(plugin)?; audiornnoise::register(plugin)?; - audioloudnorm::register(plugin) + Ok(()) } gst_plugin_define!( diff --git a/audio/claxon/src/claxondec.rs b/audio/claxon/src/claxondec/imp.rs similarity index 95% rename from audio/claxon/src/claxondec.rs rename to audio/claxon/src/claxondec/imp.rs index 34e1e99e..6833b3ea 100644 --- a/audio/claxon/src/claxondec.rs +++ b/audio/claxon/src/claxondec/imp.rs @@ -23,13 +23,14 @@ struct State { audio_info: Option, } -struct ClaxonDec { +pub struct ClaxonDec { cat: gst::DebugCategory, state: AtomicRefCell>, } impl ObjectSubclass for ClaxonDec { const NAME: &'static str = "ClaxonDec"; + type Type = super::ClaxonDec; type ParentType = gst_audio::AudioDecoder; type Instance = gst::subclass::ElementInstanceStruct; type Class = subclass::simple::ClassStruct; @@ -47,7 +48,7 @@ impl ObjectSubclass for ClaxonDec { } } - fn class_init(klass: &mut subclass::simple::ClassStruct) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Claxon FLAC decoder", "Decoder/Audio", @@ -98,13 +99,13 @@ impl ObjectImpl for ClaxonDec {} impl ElementImpl for ClaxonDec {} impl AudioDecoderImpl for ClaxonDec { - fn stop(&self, _element: &gst_audio::AudioDecoder) -> Result<(), gst::ErrorMessage> { + fn stop(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { *self.state.borrow_mut() = None; Ok(()) } - fn start(&self, _element: &gst_audio::AudioDecoder) -> Result<(), gst::ErrorMessage> { + fn start(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { *self.state.borrow_mut() = Some(State { streaminfo: None, audio_info: None, @@ -113,11 +114,7 @@ impl AudioDecoderImpl for ClaxonDec { Ok(()) } - fn set_format( - &self, - element: &gst_audio::AudioDecoder, - caps: &gst::Caps, - ) -> Result<(), gst::LoggableError> { + fn set_format(&self, element: &Self::Type, caps: &gst::Caps) -> Result<(), gst::LoggableError> { gst_debug!(self.cat, obj: element, "Setting format {:?}", caps); let mut streaminfo: Option = None; @@ -174,7 +171,7 @@ impl AudioDecoderImpl for ClaxonDec { #[allow(clippy::verbose_bit_mask)] fn handle_frame( &self, - element: &gst_audio::AudioDecoder, + element: &Self::Type, inbuf: Option<&gst::Buffer>, ) -> Result { gst_debug!(self.cat, obj: element, "Handling buffer {:?}", inbuf); @@ -217,7 +214,7 @@ impl AudioDecoderImpl for ClaxonDec { impl ClaxonDec { fn handle_streaminfo_header( &self, - element: &gst_audio::AudioDecoder, + element: &super::ClaxonDec, state: &mut State, indata: &[u8], ) -> Result { @@ -249,7 +246,7 @@ impl ClaxonDec { fn handle_data( &self, - element: &gst_audio::AudioDecoder, + element: &super::ClaxonDec, state: &mut State, indata: &[u8], ) -> Result { @@ -372,15 +369,6 @@ impl AudioDepth { } } -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "claxondec", - gst::Rank::Marginal, - ClaxonDec::get_type(), - ) -} - fn get_claxon_streaminfo(indata: &[u8]) -> Result { let mut cursor = Cursor::new(indata); let mut metadata_iter = claxon::metadata::MetadataBlockReader::new(&mut cursor); diff --git a/audio/claxon/src/claxondec/mod.rs b/audio/claxon/src/claxondec/mod.rs new file mode 100644 index 00000000..018c4ae4 --- /dev/null +++ b/audio/claxon/src/claxondec/mod.rs @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Ruben Gonzalez +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct ClaxonDec(ObjectSubclass) @extends gst_audio::AudioDecoder, gst::Element, gst::Object; +} + +unsafe impl Send for ClaxonDec {} +unsafe impl Sync for ClaxonDec {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "claxondec", + gst::Rank::Marginal, + ClaxonDec::static_type(), + ) +} diff --git a/audio/csound/src/filter.rs b/audio/csound/src/filter/imp.rs similarity index 95% rename from audio/csound/src/filter.rs rename to audio/csound/src/filter/imp.rs index e25d199d..fa85d786 100644 --- a/audio/csound/src/filter.rs +++ b/audio/csound/src/filter/imp.rs @@ -75,7 +75,7 @@ struct State { ksmps: u32, } -struct CsoundFilter { +pub struct CsoundFilter { settings: Mutex, state: Mutex>, csound: Mutex, @@ -222,7 +222,7 @@ impl CsoundFilter { } } - fn drain(&self, element: &gst_base::BaseTransform) -> Result { + fn drain(&self, element: &super::CsoundFilter) -> Result { let csound = self.csound.lock().unwrap(); let mut state_lock = self.state.lock().unwrap(); let state = state_lock.as_mut().unwrap(); @@ -293,7 +293,7 @@ impl CsoundFilter { fn generate_output( &self, - element: &gst_base::BaseTransform, + element: &super::CsoundFilter, state: &mut State, ) -> Result { let output_size = state.max_output_size(state.adapter.available()); @@ -361,6 +361,7 @@ impl CsoundFilter { impl ObjectSubclass for CsoundFilter { const NAME: &'static str = "CsoundFilter"; + type Type = super::CsoundFilter; type ParentType = gst_base::BaseTransform; type Instance = gst::subclass::ElementInstanceStruct; type Class = subclass::simple::ClassStruct; @@ -385,7 +386,7 @@ impl ObjectSubclass for CsoundFilter { } } - fn class_init(klass: &mut subclass::simple::ClassStruct) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Audio filter", "Filter/Effect/Audio", @@ -431,7 +432,7 @@ impl ObjectSubclass for CsoundFilter { } impl ObjectImpl for CsoundFilter { - fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) { + fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) { let prop = &PROPERTIES[id]; match *prop { subclass::Property("loop", ..) => { @@ -464,7 +465,7 @@ impl ObjectImpl for CsoundFilter { } } - fn get_property(&self, _obj: &glib::Object, id: usize) -> Result { + fn get_property(&self, _obj: &Self::Type, id: usize) -> Result { let prop = &PROPERTIES[id]; match *prop { @@ -492,10 +493,7 @@ impl ObjectImpl for CsoundFilter { impl ElementImpl for CsoundFilter {} impl BaseTransformImpl for CsoundFilter { - fn start( - &self, - _element: &gst_base::BaseTransform, - ) -> std::result::Result<(), gst::ErrorMessage> { + fn start(&self, _element: &Self::Type) -> std::result::Result<(), gst::ErrorMessage> { self.compile_score()?; let csound = self.csound.lock().unwrap(); @@ -509,7 +507,7 @@ impl BaseTransformImpl for CsoundFilter { Ok(()) } - fn stop(&self, element: &gst_base::BaseTransform) -> Result<(), gst::ErrorMessage> { + fn stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { let csound = self.csound.lock().unwrap(); csound.stop(); csound.reset(); @@ -520,7 +518,7 @@ impl BaseTransformImpl for CsoundFilter { Ok(()) } - fn sink_event(&self, element: &gst_base::BaseTransform, event: gst::Event) -> bool { + fn sink_event(&self, element: &Self::Type, event: gst::Event) -> bool { use gst::EventView; if let EventView::Eos(_) = event.view() { @@ -534,7 +532,7 @@ impl BaseTransformImpl for CsoundFilter { fn transform_caps( &self, - element: &gst_base::BaseTransform, + element: &Self::Type, direction: gst::PadDirection, caps: &gst::Caps, filter: Option<&gst::Caps>, @@ -586,7 +584,7 @@ impl BaseTransformImpl for CsoundFilter { fn set_caps( &self, - element: &gst_base::BaseTransform, + element: &Self::Type, incaps: &gst::Caps, outcaps: &gst::Caps, ) -> Result<(), gst::LoggableError> { @@ -646,7 +644,7 @@ impl BaseTransformImpl for CsoundFilter { fn generate_output( &self, - element: &gst_base::BaseTransform, + element: &Self::Type, ) -> Result { // 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 @@ -675,12 +673,3 @@ impl BaseTransformImpl for CsoundFilter { Ok(GenerateOutputSuccess::NoOutput) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "csoundfilter", - gst::Rank::None, - CsoundFilter::get_type(), - ) -} diff --git a/audio/csound/src/filter/mod.rs b/audio/csound/src/filter/mod.rs new file mode 100644 index 00000000..89ef3b4c --- /dev/null +++ b/audio/csound/src/filter/mod.rs @@ -0,0 +1,37 @@ +// Copyright (C) 2020 Natanael Mojica +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +use glib::glib_wrapper; +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct CsoundFilter(ObjectSubclass) @extends gst_base::BaseTransform, gst::Element, gst::Object; +} + +unsafe impl Send for CsoundFilter {} +unsafe impl Sync for CsoundFilter {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "csoundfilter", + gst::Rank::None, + CsoundFilter::static_type(), + ) +} diff --git a/audio/lewton/src/lewtondec.rs b/audio/lewton/src/lewtondec/imp.rs similarity index 96% rename from audio/lewton/src/lewtondec.rs rename to audio/lewton/src/lewtondec/imp.rs index 78401e8a..6108f1f6 100644 --- a/audio/lewton/src/lewtondec.rs +++ b/audio/lewton/src/lewtondec/imp.rs @@ -28,7 +28,7 @@ struct State { reorder_map: Option<[usize; 8]>, } -struct LewtonDec { +pub struct LewtonDec { state: AtomicRefCell>, } @@ -42,6 +42,7 @@ lazy_static! { impl ObjectSubclass for LewtonDec { const NAME: &'static str = "LewtonDec"; + type Type = super::LewtonDec; type ParentType = gst_audio::AudioDecoder; type Instance = gst::subclass::ElementInstanceStruct; type Class = subclass::simple::ClassStruct; @@ -54,7 +55,7 @@ impl ObjectSubclass for LewtonDec { } } - fn class_init(klass: &mut subclass::simple::ClassStruct) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "lewton Vorbis decoder", "Decoder/Audio", @@ -97,13 +98,13 @@ impl ObjectImpl for LewtonDec {} impl ElementImpl for LewtonDec {} impl AudioDecoderImpl for LewtonDec { - fn stop(&self, _element: &gst_audio::AudioDecoder) -> Result<(), gst::ErrorMessage> { + fn stop(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { *self.state.borrow_mut() = None; Ok(()) } - fn start(&self, _element: &gst_audio::AudioDecoder) -> Result<(), gst::ErrorMessage> { + fn start(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { *self.state.borrow_mut() = Some(State { header_bufs: (None, None, None), headerset: None, @@ -115,11 +116,7 @@ impl AudioDecoderImpl for LewtonDec { Ok(()) } - fn set_format( - &self, - element: &gst_audio::AudioDecoder, - caps: &gst::Caps, - ) -> Result<(), gst::LoggableError> { + fn set_format(&self, element: &Self::Type, caps: &gst::Caps) -> Result<(), gst::LoggableError> { gst_debug!(CAT, obj: element, "Setting format {:?}", caps); // When the caps are changing we require new headers @@ -160,7 +157,7 @@ impl AudioDecoderImpl for LewtonDec { Ok(()) } - fn flush(&self, element: &gst_audio::AudioDecoder, _hard: bool) { + fn flush(&self, element: &Self::Type, _hard: bool) { gst_debug!(CAT, obj: element, "Flushing"); let mut state_guard = self.state.borrow_mut(); @@ -171,7 +168,7 @@ impl AudioDecoderImpl for LewtonDec { fn handle_frame( &self, - element: &gst_audio::AudioDecoder, + element: &Self::Type, inbuf: Option<&gst::Buffer>, ) -> Result { gst_debug!(CAT, obj: element, "Handling buffer {:?}", inbuf); @@ -218,7 +215,7 @@ impl AudioDecoderImpl for LewtonDec { impl LewtonDec { fn handle_header( &self, - element: &gst_audio::AudioDecoder, + element: &super::LewtonDec, state: &mut State, inbuf: &gst::Buffer, indata: &[u8], @@ -254,7 +251,7 @@ impl LewtonDec { fn initialize( &self, - element: &gst_audio::AudioDecoder, + element: &super::LewtonDec, state: &mut State, ) -> Result<(), gst::FlowError> { let (ident_buf, comment_buf, setup_buf) = match state.header_bufs { @@ -369,7 +366,7 @@ impl LewtonDec { fn handle_data( &self, - element: &gst_audio::AudioDecoder, + element: &super::LewtonDec, state: &mut State, indata: &[u8], ) -> Result { @@ -473,15 +470,6 @@ impl LewtonDec { } } -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "lewtondec", - gst::Rank::Marginal, - LewtonDec::get_type(), - ) -} - // http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 const VORBIS_CHANNEL_POSITIONS: [[gst_audio::AudioChannelPosition; 8]; 8] = [ [ diff --git a/audio/lewton/src/lewtondec/mod.rs b/audio/lewton/src/lewtondec/mod.rs new file mode 100644 index 00000000..b98d8098 --- /dev/null +++ b/audio/lewton/src/lewtondec/mod.rs @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct LewtonDec(ObjectSubclass) @extends gst_audio::AudioDecoder, gst::Element, gst::Object; +} + +unsafe impl Send for LewtonDec {} +unsafe impl Sync for LewtonDec {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "lewtondec", + gst::Rank::Marginal, + LewtonDec::static_type(), + ) +}