Skip to content

Commit

Permalink
added some more utilities and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
w-ensink committed Dec 20, 2022
1 parent f3c5608 commit 17cd70a
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 8 deletions.
15 changes: 14 additions & 1 deletion src/units/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ use crate::units::{SampleRate, Samples, Seconds};
pub struct Duration(Seconds);

impl Duration {
/// Converts the duration to samples using the given sample rate.
/// Converts the duration to samples using the given sample rate:
/// ```
/// use rabu::units::{Duration, SampleRate, Samples};
/// let duration = Duration::from_secs_f64(5.0);
/// let sample_rate = SampleRate::from(44100);
/// let num_samples = duration.to_samples(sample_rate);
/// assert_eq!(num_samples, Samples::from(220500));
/// ```
pub fn to_samples(&self, sr: SampleRate) -> Samples {
self.0.to_samples(sr)
}
Expand All @@ -29,6 +36,12 @@ impl Duration {
}
}

impl PartialEq<Seconds> for Duration {
fn eq(&self, other: &Seconds) -> bool {
self.as_seconds() == *other
}
}

impl From<Seconds> for Duration {
fn from(value: Seconds) -> Self {
Self::from_secs_f64(value.as_f64())
Expand Down
21 changes: 20 additions & 1 deletion src/units/percentage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,23 @@ use serde::{Deserialize, Serialize};
/// Represents a percentage, e.g. the export progress.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Percentage(pub f64);
pub struct Percentage(f64);

macro_rules! impl_float_conversions {
($float_type: ty) => {
impl From<$float_type> for Percentage {
fn from(value: $float_type) -> Self {
Self(value as _)
}
}

impl From<Percentage> for $float_type {
fn from(value: Percentage) -> Self {
value.0 as _
}
}
};
}

impl_float_conversions!(f32);
impl_float_conversions!(f64);
36 changes: 32 additions & 4 deletions src/units/sample_rate.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::units::{Duration, Seconds};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

Expand All @@ -8,23 +9,50 @@ pub struct SampleRate(u32);

impl SampleRate {
/// Gives back the raw value as a `u32`.
pub fn value(&self) -> u32 {
pub fn as_u32(&self) -> u32 {
self.0
}

/// Gives back the raw value as a `usize`.
pub fn as_usize(&self) -> usize {
self.value() as usize
self.as_u32() as usize
}

/// Gives back the raw value as a `f64`.
pub fn as_f64(&self) -> f64 {
self.value() as f64
self.as_u32() as f64
}

/// Gives back the raw value as a `u64`.
pub fn as_u64(&self) -> u64 {
self.value() as u64
self.as_u32() as u64
}

/// Gets the duration between two consecutive samples:
/// Gets the time in seconds between tho consecutive samples:
/// ```
/// use rabu::units::{Duration, SampleRate};
///
/// let sample_rate = SampleRate::from(20);
/// let period = sample_rate.time_between_samples();
///
/// assert_eq!(period, Duration::from_secs_f64(0.05));
/// ```
pub fn time_between_samples(&self) -> Duration {
Duration::from_secs_f64(1.0 / self.as_f64())
}

/// Gets the time in seconds between tho consecutive samples:
/// ```
/// use rabu::units::{SampleRate, Seconds};
///
/// let sample_rate = SampleRate::from(10);
/// let period_secs = sample_rate.secs_between_samples();
///
/// assert_eq!(period_secs, Seconds::from(0.1));
/// ```
pub fn secs_between_samples(&self) -> Seconds {
Seconds::from(1.0 / self.as_f64())
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/units/samples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Samples {

/// Converts to seconds using the given sample rate.
pub fn to_seconds(&self, sr: SampleRate) -> Seconds {
Seconds::from(self.as_u64() as f64 / sr.value() as f64)
Seconds::from(self.as_u64() as f64 / sr.as_u32() as f64)
}

/// Gives back the raw value as a `usize`.
Expand Down
2 changes: 1 addition & 1 deletion src/units/seconds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct Seconds(f64);
impl Seconds {
/// Convert to samples using the given sample rate.
pub fn to_samples(&self, sr: SampleRate) -> Samples {
Samples::from((self.as_f64() * sr.value() as f64) as u64)
Samples::from((self.as_f64() * sr.as_u32() as f64) as u64)
}

/// Gives back the raw value in f64.
Expand Down
25 changes: 25 additions & 0 deletions src/units/time_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ use serde::{Deserialize, Serialize};
use crate::units::{Duration, Seconds};

/// Represents a time point in the audio domain, e.g. the start position of a file.
/// Has the correct conversions when adding/subtracting other types to/from it:
/// ```
/// use rabu::units::{Duration, Seconds, TimePoint};
///
/// let t1 = TimePoint::from_secs_f64(10.0);
/// let t2 = TimePoint::from(Seconds::from(12.0));
/// let time_between = t2 - t1;
///
/// assert_eq!(time_between, Duration::from_secs_f64(2.0));
///
/// let next_time_point = t2 + Duration::from_secs_f64(2.0);
/// assert_eq!(next_time_point, TimePoint::from_secs_f64(14.0));
///
/// let earlier_time_point = t2 - Duration::from_secs_f64(2.0);
/// assert_eq!(earlier_time_point, t1);
///
/// let next_time_point = t2 + Seconds::from(0.5);
/// assert_eq!(next_time_point, TimePoint::from_secs_f64(12.5));
/// ```
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TimePoint(Seconds);
Expand All @@ -27,6 +46,12 @@ impl TimePoint {
}
}

impl PartialEq<Seconds> for TimePoint {
fn eq(&self, other: &Seconds) -> bool {
self.as_seconds() == *other
}
}

impl From<Seconds> for TimePoint {
fn from(value: Seconds) -> Self {
value.as_time_point()
Expand Down
19 changes: 19 additions & 0 deletions src/units/time_section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@ pub struct TimeSection {

impl TimeSection {
/// Returns the overlap (if any) between this time section and another.
/// This should also be used in order to find out whether there is overlap or not.
/// ```
/// use rabu::units::{Seconds, TimePoint, TimeSection};
///
/// let section_1 = TimeSection {
/// start: Seconds::from(1.0).into(),
/// duration: Seconds::from(2.0).into(),
/// };
///
/// let section_2 = TimeSection {
/// start: Seconds::from(1.5).into(),
/// duration: Seconds::from(1.0).into(),
/// };
///
/// let overlap = section_1.get_overlap(section_2).unwrap();
///
/// assert_eq!(overlap.start, Seconds::from(1.5));
/// assert_eq!(overlap.duration, Seconds::from(1.0));
/// ```
pub fn get_overlap(&self, other: Self) -> Option<Self> {
if self.end() <= other.start || other.end() <= self.start {
return None;
Expand Down

0 comments on commit 17cd70a

Please sign in to comment.