diff options
Diffstat (limited to 'cras/src/server/rust')
-rw-r--r-- | cras/src/server/rust/.gitignore | 1 | ||||
-rw-r--r-- | cras/src/server/rust/Cargo.toml | 17 | ||||
-rw-r--r-- | cras/src/server/rust/binding_generator/Cargo.toml | 8 | ||||
-rw-r--r-- | cras/src/server/rust/binding_generator/src/main.rs | 27 | ||||
-rw-r--r-- | cras/src/server/rust/src/headers/rate_estimator.h | 85 | ||||
-rw-r--r-- | cras/src/server/rust/src/rate_estimator.rs | 188 | ||||
-rw-r--r-- | cras/src/server/rust/src/rate_estimator_bindings.rs | 110 |
7 files changed, 0 insertions, 436 deletions
diff --git a/cras/src/server/rust/.gitignore b/cras/src/server/rust/.gitignore deleted file mode 100644 index 2f7896d1..00000000 --- a/cras/src/server/rust/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target/ diff --git a/cras/src/server/rust/Cargo.toml b/cras/src/server/rust/Cargo.toml deleted file mode 100644 index afebda83..00000000 --- a/cras/src/server/rust/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "cras_rust" -version = "0.1.0" -authors = ["The Chromium OS Authors"] -edition = "2018" - -[lib] -path = "src/rate_estimator.rs" -crate-type = ["staticlib"] - -[dependencies] -libc = "0.2.44" - -[profile.release] -lto = true -panic = "abort" -overflow-checks = true diff --git a/cras/src/server/rust/binding_generator/Cargo.toml b/cras/src/server/rust/binding_generator/Cargo.toml deleted file mode 100644 index 1ec73483..00000000 --- a/cras/src/server/rust/binding_generator/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "binding_generator" -version = "0.1.0" -authors = ["The Chromium OS Authors"] -edition = "2018" - -[dependencies] -cbindgen = "*" diff --git a/cras/src/server/rust/binding_generator/src/main.rs b/cras/src/server/rust/binding_generator/src/main.rs deleted file mode 100644 index f7803968..00000000 --- a/cras/src/server/rust/binding_generator/src/main.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -extern crate cbindgen; - -use cbindgen::Builder; - -const HEADER: &str = "// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Generated from files in cras/src/server/rust/src in adhd."; - -fn main() { - Builder::new() - .with_src("../src/rate_estimator.rs") - .rename_item("RateEstimator", "rate_estimator") - .rename_item("timespec", "struct timespec") - .with_no_includes() - .with_sys_include("time.h") - .with_include_guard("RATE_ESTIMATOR_H_") - .with_language(cbindgen::Language::C) - .with_header(HEADER) - .generate() - .expect("Unable to generate bindings") - .write_to_file("../src/headers/rate_estimator.h"); -} diff --git a/cras/src/server/rust/src/headers/rate_estimator.h b/cras/src/server/rust/src/headers/rate_estimator.h deleted file mode 100644 index 3ac9cfa9..00000000 --- a/cras/src/server/rust/src/headers/rate_estimator.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Generated from files in cras/src/server/rust/src in adhd. - -#ifndef RATE_ESTIMATOR_H_ -#define RATE_ESTIMATOR_H_ - -#include <time.h> - -/** - * An estimator holding the required information to determine the actual frame - * rate of an audio device. - * - * # Members - * * `last_level` - Buffer level of the audio device at last check time. - * * `level_diff` - Number of frames written to or read from audio device - * since the last check time. Rate estimator will use this - * change plus the difference of buffer level to derive the - * number of frames audio device has actually processed. - * * `window_start` - The start time of the current window. - * * `window_size` - The size of the window. - * * `window_frames` - The number of frames accumulated in current window. - * * `lsq` - The helper used to estimate sample rate. - * * `smooth_factor` - A scaling factor used to average the previous and new - * rate estimates to ensure that estimates do not change - * too quickly. - * * `estimated_rate` - The estimated rate at which samples are consumed. - */ -typedef struct rate_estimator rate_estimator; - -/** - * # Safety - * - * To use this function safely, `re` must be a pointer returned from - * rate_estimator_create, or null. - */ -void rate_estimator_add_frames(rate_estimator *re, int frames); - -/** - * # Safety - * - * To use this function safely, `re` must be a pointer returned from - * rate_estimator_create, or null, and `now` must be a valid pointer to a - * timespec. - */ -int32_t rate_estimator_check(rate_estimator *re, int level, - const struct timespec *now); - -/** - * # Safety - * - * To use this function safely, `window_size` must be a valid pointer to a - * timespec. - */ -rate_estimator *rate_estimator_create(unsigned int rate, - const struct timespec *window_size, - double smooth_factor); - -/** - * # Safety - * - * To use this function safely, `re` must be a pointer returned from - * rate_estimator_create, or null. - */ -void rate_estimator_destroy(rate_estimator *re); - -/** - * # Safety - * - * To use this function safely, `re` must be a pointer returned from - * rate_estimator_create, or null. - */ -double rate_estimator_get_rate(const rate_estimator *re); - -/** - * # Safety - * - * To use this function safely, `re` must be a pointer returned from - * rate_estimator_create, or null. - */ -void rate_estimator_reset_rate(rate_estimator *re, unsigned int rate); - -#endif /* RATE_ESTIMATOR_H_ */ diff --git a/cras/src/server/rust/src/rate_estimator.rs b/cras/src/server/rust/src/rate_estimator.rs deleted file mode 100644 index 585f346b..00000000 --- a/cras/src/server/rust/src/rate_estimator.rs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -pub mod rate_estimator_bindings; - -use std::error; -use std::fmt; -use std::time::Duration; - -#[derive(Debug)] -pub enum Error { - InvalidSmoothFactor(f64), -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Error::*; - match self { - InvalidSmoothFactor(sf) => write!(f, "Smooth factor {} is not between 0.0 and 1.0", sf), - } - } -} - -type Result<T> = std::result::Result<T, Error>; - -const MAX_RATE_SKEW: f64 = 100.0; - -/// Hold information to calculate linear least square from -/// several (x, y) samples. -#[derive(Debug, Default)] -struct LeastSquares { - sum_x: f64, - sum_y: f64, - sum_xy: f64, - sum_x2: f64, - num_samples: u32, -} - -impl LeastSquares { - fn new() -> Self { - Self::default() - } - - fn add_sample(&mut self, x: f64, y: f64) { - self.sum_x += x; - self.sum_y += y; - self.sum_xy += x * y; - self.sum_x2 += x * x; - self.num_samples += 1; - } - - fn best_fit_slope(&self) -> f64 { - let num = self.num_samples as f64 * self.sum_xy - self.sum_x * self.sum_y; - let den = self.num_samples as f64 * self.sum_x2 - self.sum_x * self.sum_x; - num / den - } -} - -/// An estimator holding the required information to determine the actual frame -/// rate of an audio device. -/// -/// # Members -/// * `last_level` - Buffer level of the audio device at last check time. -/// * `level_diff` - Number of frames written to or read from audio device -/// since the last check time. Rate estimator will use this -/// change plus the difference of buffer level to derive the -/// number of frames audio device has actually processed. -/// * `window_start` - The start time of the current window. -/// * `window_size` - The size of the window. -/// * `window_frames` - The number of frames accumulated in current window. -/// * `lsq` - The helper used to estimate sample rate. -/// * `smooth_factor` - A scaling factor used to average the previous and new -/// rate estimates to ensure that estimates do not change -/// too quickly. -/// * `estimated_rate` - The estimated rate at which samples are consumed. -pub struct RateEstimator { - last_level: i32, - level_diff: i32, - window_start: Option<Duration>, - window_size: Duration, - window_frames: u32, - lsq: LeastSquares, - smooth_factor: f64, - estimated_rate: f64, -} - -impl RateEstimator { - /// Creates a rate estimator. - /// - /// # Arguments - /// * `rate` - The initial value to estimate rate from. - /// * `window_size` - The window size of the rate estimator. - /// * `smooth_factor` - The coefficient used to calculate moving average - /// from old estimated rate values. Must be between - /// 0.0 and 1.0 - /// - /// # Errors - /// * If `smooth_factor` is not between 0.0 and 1.0 - pub fn try_new(rate: u32, window_size: Duration, smooth_factor: f64) -> Result<Self> { - if smooth_factor < 0.0 || smooth_factor > 1.0 { - return Err(Error::InvalidSmoothFactor(smooth_factor)); - } - - Ok(RateEstimator { - last_level: 0, - level_diff: 0, - window_start: None, - window_size, - window_frames: 0, - lsq: LeastSquares::new(), - smooth_factor, - estimated_rate: rate as f64, - }) - } - - /// Resets the estimated rate - /// - /// Reset the estimated rate to `rate`, and erase all collected data. - pub fn reset_rate(&mut self, rate: u32) { - self.last_level = 0; - self.level_diff = 0; - self.window_start = None; - self.window_frames = 0; - self.lsq = LeastSquares::new(); - self.estimated_rate = rate as f64; - } - - /// Adds additional frames transmitted to/from audio device. - /// - /// # Arguments - /// * `frames` - The number of frames written to the device. For input, - /// this should be negative to indicate how many samples - /// were read. - pub fn add_frames(&mut self, frames: i32) { - self.level_diff += frames; - } - - /// Gets the estimated rate. - pub fn get_estimated_rate(&self) -> f64 { - self.estimated_rate - } - - /// Check the timestamp and buffer level difference since last check time, - /// and use them as a new sample to update the estimated rate. - /// - /// # Arguments - /// * `level` - The current buffer level of audio device. - /// * `now` - The time at which this function is called. - /// - /// # Returns - /// True if the estimated rate is updated and window is reset, - /// otherwise false. - pub fn update_estimated_rate(&mut self, level: i32, now: Duration) -> bool { - let start = match self.window_start { - None => { - self.window_start = Some(now); - return false; - } - Some(t) => t, - }; - - let delta = match now.checked_sub(start) { - Some(d) => d, - None => return false, - }; - self.window_frames += (self.last_level - level + self.level_diff).abs() as u32; - self.level_diff = 0; - self.last_level = level; - - let secs = (delta.as_secs() as f64) + delta.subsec_nanos() as f64 / 1_000_000_000.0; - self.lsq.add_sample(secs, self.window_frames as f64); - if delta > self.window_size && self.lsq.num_samples > 1 { - let rate = self.lsq.best_fit_slope(); - if (self.estimated_rate - rate).abs() < MAX_RATE_SKEW { - self.estimated_rate = - rate * (1.0 - self.smooth_factor) + self.estimated_rate * self.smooth_factor; - } - self.lsq = LeastSquares::new(); - self.window_start = Some(now); - self.window_frames = 0; - return true; - } - false - } -} diff --git a/cras/src/server/rust/src/rate_estimator_bindings.rs b/cras/src/server/rust/src/rate_estimator_bindings.rs deleted file mode 100644 index 3073ba73..00000000 --- a/cras/src/server/rust/src/rate_estimator_bindings.rs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use std::time::Duration; - -use libc; - -use crate::RateEstimator; - -/// # Safety -/// -/// To use this function safely, `window_size` must be a valid pointer to a -/// timespec. -#[no_mangle] -pub unsafe extern "C" fn rate_estimator_create( - rate: libc::c_uint, - window_size: *const libc::timespec, - smooth_factor: libc::c_double, -) -> *mut RateEstimator { - if window_size.is_null() { - return std::ptr::null_mut::<RateEstimator>(); - } - - let ts = &*window_size; - let window = Duration::new(ts.tv_sec as u64, ts.tv_nsec as u32); - - match RateEstimator::try_new(rate, window, smooth_factor) { - Ok(re) => Box::into_raw(Box::new(re)), - Err(_) => std::ptr::null_mut::<RateEstimator>(), - } -} - -/// # Safety -/// -/// To use this function safely, `re` must be a pointer returned from -/// rate_estimator_create, or null. -#[no_mangle] -pub unsafe extern "C" fn rate_estimator_destroy(re: *mut RateEstimator) { - if re.is_null() { - return; - } - - drop(Box::from_raw(re)); -} - -/// # Safety -/// -/// To use this function safely, `re` must be a pointer returned from -/// rate_estimator_create, or null. -#[no_mangle] -pub unsafe extern "C" fn rate_estimator_add_frames(re: *mut RateEstimator, frames: libc::c_int) { - if re.is_null() { - return; - } - - (*re).add_frames(frames) -} - -/// # Safety -/// -/// To use this function safely, `re` must be a pointer returned from -/// rate_estimator_create, or null, and `now` must be a valid pointer to a -/// timespec. -#[no_mangle] -pub unsafe extern "C" fn rate_estimator_check( - re: *mut RateEstimator, - level: libc::c_int, - now: *const libc::timespec, -) -> i32 { - if re.is_null() || now.is_null() { - return 0; - } - - let ts = &*now; - if ts.tv_sec < 0 || ts.tv_nsec < 0 { - return 0; - } - let secs = ts.tv_sec as u64 + (ts.tv_nsec / 1_000_000_000) as u64; - let nsecs = (ts.tv_nsec % 1_000_000_000) as u32; - let now = Duration::new(secs, nsecs); - - (*re).update_estimated_rate(level, now) as i32 -} - -/// # Safety -/// -/// To use this function safely, `re` must be a pointer returned from -/// rate_estimator_create, or null. -#[no_mangle] -pub unsafe extern "C" fn rate_estimator_get_rate(re: *const RateEstimator) -> libc::c_double { - if re.is_null() { - return 0.0; - } - - (*re).get_estimated_rate() -} - -/// # Safety -/// -/// To use this function safely, `re` must be a pointer returned from -/// rate_estimator_create, or null. -#[no_mangle] -pub unsafe extern "C" fn rate_estimator_reset_rate(re: *mut RateEstimator, rate: libc::c_uint) { - if re.is_null() { - return; - } - - (*re).reset_rate(rate) -} |