1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
use std::fmt;

use crate::backend::sample_rescaling::f32_to_i16;
use crate::backend::waveform::Waveform;
use serde::{Deserialize, Serialize};

/// Represents a fixed-length audio waveform as a `Vec<i16>`.
///
/// This struct should only be used when needed to store or transmit
/// uncompressed audio data. For more operations on audio, it is better
/// to work with a [`FloatWaveform`](crate::FloatWaveform).
///
/// # Examples
/// ```
/// use babycat::{FloatWaveform, IntWaveform, Waveform};
///
///
/// // The FloatWaveform stores audio samples as f32 values between -1.0 and 1.0.
/// let float_waveform = FloatWaveform::from_file(
///    "audio-for-tests/circus-of-freaks/track.mp3",
///     Default::default(),
/// ).unwrap();
/// assert_eq!(
///     format!("{:?}", float_waveform),
///     "FloatWaveform { frame_rate_hz: 44100, num_channels: 2, num_frames: 2492928}"
/// );
/// println!("{:?}", &float_waveform.interleaved_samples()[30000..30005]);
/// // [0.0238994, 0.08098572, 0.0208567, 0.09139156, 0.015145444]
///
///
/// // The Intwaveform stores audio samples as i16 values between -32768 and 32767.
/// let int_waveform = IntWaveform::from(float_waveform);
/// assert_eq!(
///     format!("{:?}", int_waveform),
///     "IntWaveform { frame_rate_hz: 44100, num_channels: 2, num_frames: 2492928}"
/// );
/// println!("{:?}", &int_waveform.interleaved_samples()[30000..30005]);
/// // [783, 2653, 683, 2994, 496]
/// ```
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IntWaveform {
    interleaved_samples: Vec<i16>,
    frame_rate_hz: u32,
    num_channels: u32,
    num_frames: u64,
}

impl From<crate::backend::float_waveform::FloatWaveform> for IntWaveform {
    fn from(item: crate::backend::float_waveform::FloatWaveform) -> Self {
        let buffer: Vec<i16> = item
            .interleaved_samples()
            .iter()
            .map(|val| f32_to_i16(*val))
            .collect();

        IntWaveform {
            interleaved_samples: buffer,
            frame_rate_hz: item.frame_rate_hz(),
            num_channels: item.num_channels(),
            num_frames: item.num_frames(),
        }
    }
}

// We manually implement the debug trait so that we don't
// print out giant vectors.
impl fmt::Debug for IntWaveform {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "IntWaveform {{ frame_rate_hz: {}, num_channels: {}, num_frames: {}}}",
            self.frame_rate_hz(),
            self.num_channels(),
            self.num_frames()
        )
    }
}

impl crate::backend::waveform::Waveform<i16> for IntWaveform {
    fn new(frame_rate_hz: u32, num_channels: u32, interleaved_samples: Vec<i16>) -> Self {
        let num_frames = interleaved_samples.len() as u64 / num_channels as u64;
        IntWaveform {
            interleaved_samples,
            frame_rate_hz,
            num_channels,
            num_frames,
        }
    }

    fn frame_rate_hz(&self) -> u32 {
        self.frame_rate_hz
    }

    fn num_channels(&self) -> u32 {
        self.num_channels
    }

    fn num_frames(&self) -> u64 {
        self.num_frames
    }

    fn interleaved_samples(&self) -> &[i16] {
        &self.interleaved_samples
    }
}