nsys-signal-utils 0.0.3

Signal processing utilities
Documentation
//! Functions on PCM encoded signal data

pub fn center (samples : &mut [i16]) -> &mut [i16] {
  let max = *samples.iter().max().unwrap();
  let min = *samples.iter().min().unwrap();
  let d   = -(max + min) / 2;
  for sample in samples.iter_mut() {
    *sample += d;
  }
  samples
}

/// Centers signal before normalizing
pub fn normalize_peak (samples : &mut [i16], to : i16) -> &mut [i16] {
  let safeabs = |i| match i {
    &std::i16::MIN => std::i16::MAX,
    i              => i.abs()
  };
  let samples = center (samples);
  let max_abs = *samples.iter().max_by_key (|sample| safeabs (sample))
    .unwrap();
  let scale   = to.abs() as f64 / max_abs as f64;
  for sample in samples.iter_mut() {
    *sample = (scale * *sample as f64) as i16
  }
  samples
}


/// ```
/// # extern crate signal_utils;
/// # fn main() {
/// # use signal_utils::pcm::trim_silence;
/// let pcm = vec![0, 0, 0, 1, 2, 3, 4, 0, 0];
/// debug_assert_eq!(trim_silence (&pcm[..]), &pcm[3..7]);
/// let pcm = vec![1, 2, 3, 4];
/// debug_assert_eq!(trim_silence (&pcm[..]), &[1,2,3,4]);
/// # }
/// ```
pub fn trim_silence (samples : &[i16]) -> &[i16] {
  let mut start = 0;
  for i in 0..samples.len() {
    start = i;
    if samples[i] != 0 {
      break
    }
  }
  let mut end = samples.len();
  for i in 1..samples.len() {
    let i = samples.len() - i;
    end = i+1;
    dbg!(end);
    if samples[i] != 0 {
      break
    }
  }
  if end <= start {
    start = 0;
    end   = samples.len();
  }
  &(*samples)[start..end]
}

/// ```
/// # extern crate signal_utils;
/// # fn main() {
/// # use signal_utils::pcm::trim_zeros;
/// let pcm = vec![0, 1, 2, -3, -4, 5, 6, 7, -8, 9, -10, -11];
/// debug_assert_eq!(trim_zeros (&pcm[..]), &pcm[0..10]);
/// let pcm = vec![1, 1, 0, 1, 1, 1, 0, 1, 1];
/// debug_assert_eq!(trim_zeros (&pcm[..]), &[0,1,1,1,0]);
/// # }
/// ```
pub fn trim_zeros (samples : &[i16]) -> &[i16] {
  let mut start = 0;
  for i in 0..samples.len()-1 {
    start = i+1;
    if samples[i] == 0 {
      start = i;
      break
    }
    match ((*samples)[i].is_positive(), (*samples)[i+1].is_positive()) {
      (true, false) | (false, true) => break,
      _ => {}
    }
  }
  let mut end = samples.len();
  for i in 1..samples.len() {
    let i = samples.len() - i;
    end = i;
    if samples[i] == 0 {
      break
    }
    match ((*samples)[i].is_positive(), (*samples)[i-1].is_positive()) {
      (true, false) | (false, true) => break,
      _ => {}
    }
  }
  if end <= start {
    start = 0;
    end   = samples.len();
  }
  &(*samples)[start..end]
}