pocketstation 1.0.0

Source-aware desktop audio Session SDK
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TimelineMapping {
    pub source_origin_ns: u64,
    pub session_origin_ns: u64,
}

impl TimelineMapping {
    pub const fn new(source_origin_ns: u64, session_origin_ns: u64) -> Self {
        Self {
            source_origin_ns,
            session_origin_ns,
        }
    }

    pub fn normalize_timestamp_ns(self, source_timestamp_ns: u64) -> Option<u64> {
        if source_timestamp_ns >= self.source_origin_ns {
            self.session_origin_ns
                .checked_add(source_timestamp_ns - self.source_origin_ns)
        } else {
            self.session_origin_ns
                .checked_sub(self.source_origin_ns - source_timestamp_ns)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn given_later_source_timestamp_when_normalized_then_session_delta_is_preserved() {
        let mapping = TimelineMapping::new(1_000, 4_000);

        assert_eq!(mapping.normalize_timestamp_ns(1_250), Some(4_250));
    }

    #[test]
    fn given_earlier_source_timestamp_when_normalized_then_session_delta_is_preserved() {
        let mapping = TimelineMapping::new(1_000, 4_000);

        assert_eq!(mapping.normalize_timestamp_ns(750), Some(3_750));
    }

    #[test]
    fn given_unrepresentable_timestamp_when_normalized_then_none_is_returned() {
        let mapping = TimelineMapping::new(10, 5);

        assert_eq!(mapping.normalize_timestamp_ns(0), None);
    }
}