pub struct CepstrumExtractor<T: CepFloat> { /* private fields */ }Expand description
The main struct of this crate; can be used to extract both complex and real cepstrums from a signal.
As far as possible, when used multiple times, this struct will try to re-use internal data.
§Examples
use cepstrum_extractor::num_complex::Complex;
use cepstrum_extractor::num_traits::Zero;
use cepstrum_extractor::{CepstrumExtractor, RealToComplex};
use cepstrum_extractor::windows::hann::Hann;
let extractor = CepstrumExtractor::new(10);
// Different ways to obtain a vector of complex
let signal: Vec<Complex<f32>> = vec![Complex::zero(); 10];
let signal: Vec<Complex<f32>> = [0.; 10].to_complex_vec();
let signal: Vec<Complex<f32>> = [0.; 10].hann_complex();
// Create new vectors of len `signal.len() / 2`
let real_ceps = extractor.rceps_to_vec(&signal);
let complex_ceps = extractor.cceps_to_vec(&signal);
// Use passed slices (useful range will be `0..len/2`)
let mut real_ceps = signal.clone();
extractor.rceps_mut(&mut real_ceps);
real_ceps.truncate(real_ceps.len() / 2);
let mut complex_ceps = signal.clone();
extractor.cceps_mut(&mut complex_ceps);
complex_ceps.truncate(complex_ceps.len() / 2);§Use in a concurrent environment
This extractor can be placed in an Arc to be shared between different threads.
You can use plain threads or external tools like Tokio and Rayon to perform parallel
computations. It is important to note, however, that each thread must always use the same
index to ensure that the same part of the extractor is not being used by another thread
at the same time. The *_with_instance_* methods require a usize parameter, representing
the index of the thread that is calling the method.
As it is built, the extractor has only one instance available, so it can be used only by one thread
at a time. By calling Self::extend_instances, you can increase the number of instances.
If you create an extractor with 10 available instances, thread indices are numbered from 0 to 9.
§Examples
use std::sync::Arc;
use std::thread;
use cepstrum_extractor::num_complex::Complex;
use cepstrum_extractor::num_traits::Zero;
use cepstrum_extractor::CepstrumExtractor;
const THREADS: usize = 2;
const CEP_LEN: usize = 10;
let extractor: Arc<CepstrumExtractor<f32>> = Arc::new(CepstrumExtractor::new(CEP_LEN));
extractor.extend_instances(THREADS);
let signal: Vec<Complex<f32>> = vec![Complex::zero(); 100];
thread::scope(|s| {
for (idx, thread_chunk) in signal.chunks(signal.len() / THREADS).enumerate() {
let ex = extractor.clone();
s.spawn(move || {
for chunk in thread_chunk.chunks(CEP_LEN) {
let complex_ceps = ex.cceps_with_instance_to_vec(chunk, idx);
let real_ceps = ex.rceps_with_instance_to_vec(chunk, idx);
}
});
}
});Implementations§
Source§impl<T: CepFloat> CepstrumExtractor<T>
impl<T: CepFloat> CepstrumExtractor<T>
Sourcepub fn new(win_len: usize) -> CepstrumExtractor<T>
pub fn new(win_len: usize) -> CepstrumExtractor<T>
Builds a new extractor with a single instance available, i.e. an extractor to be used in a single-threaded environment.
Sourcepub fn extend_instances(&self, new_count: usize)
pub fn extend_instances(&self, new_count: usize)
Increases the number of instances available for parallel computing to new_count.
Sourcepub fn rceps_mut(&self, signal: &mut [Complex<T>])
pub fn rceps_mut(&self, signal: &mut [Complex<T>])
Extract the real cepstrum mutating the provided slice.
As with spectrums, the meaningful area will be signal[0..signal.len() / 2].
Sourcepub fn rceps_to_vec(&self, signal: &[Complex<T>]) -> Vec<Complex<T>>
pub fn rceps_to_vec(&self, signal: &[Complex<T>]) -> Vec<Complex<T>>
Extract the real cepstrum placing the result in a new vector.
Such a vector will be already truncated to half signal.len().
Sourcepub fn rceps_with_instance_mut(
&self,
signal: &mut [Complex<T>],
instance: usize,
)
pub fn rceps_with_instance_mut( &self, signal: &mut [Complex<T>], instance: usize, )
As Self::rceps_mut, but uses the passed instance at index instance.
As with spectrums, the meaningful area will be signal[0..signal.len() / 2].
Sourcepub fn rceps_with_instance_to_vec(
&self,
signal: &[Complex<T>],
instance: usize,
) -> Vec<Complex<T>>
pub fn rceps_with_instance_to_vec( &self, signal: &[Complex<T>], instance: usize, ) -> Vec<Complex<T>>
As Self::rceps_to_vec, but uses the passed instance at index instance.
Sourcepub fn cceps_mut(&self, signal: &mut [Complex<T>])
pub fn cceps_mut(&self, signal: &mut [Complex<T>])
Extract the complex cepstrum mutating the provided slice.
As with spectrums, the meaningful area will be signal[0..signal.len() / 2].
Sourcepub fn cceps_to_vec(&self, signal: &[Complex<T>]) -> Vec<Complex<T>>
pub fn cceps_to_vec(&self, signal: &[Complex<T>]) -> Vec<Complex<T>>
Extract the complex cepstrum placing the result in a new vector.
Such a vector will be already truncated to half signal.len().
Sourcepub fn cceps_with_instance_mut(
&self,
signal: &mut [Complex<T>],
instance: usize,
)
pub fn cceps_with_instance_mut( &self, signal: &mut [Complex<T>], instance: usize, )
As Self::cceps_mut, but uses the passed instance at index instance.
As with spectrums, the meaningful area will be signal[0..signal.len() / 2].
Sourcepub fn cceps_with_instance_to_vec(
&self,
signal: &[Complex<T>],
instance: usize,
) -> Vec<Complex<T>>
pub fn cceps_with_instance_to_vec( &self, signal: &[Complex<T>], instance: usize, ) -> Vec<Complex<T>>
As Self::cceps_to_vec, but uses the passed instance at index instance.