Get rid of the weird thingie...
This commit is contained in:
parent
8d0dbe797c
commit
544c0084ff
7 changed files with 83 additions and 187 deletions
|
@ -3,26 +3,22 @@
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
//use super::helpers::{sqrt4_to_pow4, TrigSignal, Trigger};
|
//use super::helpers::{sqrt4_to_pow4, TrigSignal, Trigger};
|
||||||
use crate::nodes::SCOPE_SAMPLES;
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
|
use crate::nodes::SCOPE_SAMPLES;
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
use crate::UnsyncFloatBuf;
|
use crate::ScopeHandle;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A simple signal scope
|
/// A simple signal scope
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Scope {
|
pub struct Scope {
|
||||||
buf: [UnsyncFloatBuf; 3],
|
handle: Arc<ScopeHandle>,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
pub fn new(_nid: &NodeId) -> Self {
|
pub fn new(_nid: &NodeId) -> Self {
|
||||||
let buf = [
|
Self { handle: ScopeHandle::new_shared(), idx: 0 }
|
||||||
UnsyncFloatBuf::new_with_len(1),
|
|
||||||
UnsyncFloatBuf::new_with_len(1),
|
|
||||||
UnsyncFloatBuf::new_with_len(1),
|
|
||||||
];
|
|
||||||
Self { buf, idx: 0 }
|
|
||||||
}
|
}
|
||||||
pub const in1: &'static str = "Scope in1\nSignal input 1.\nRange: (-1..1)\n";
|
pub const in1: &'static str = "Scope in1\nSignal input 1.\nRange: (-1..1)\n";
|
||||||
pub const in2: &'static str = "Scope in2\nSignal input 2.\nRange: (-1..1)\n";
|
pub const in2: &'static str = "Scope in2\nSignal input 2.\nRange: (-1..1)\n";
|
||||||
|
@ -38,8 +34,8 @@ record up to 24 signals. The received signal will be forwarded to the GUI and
|
||||||
you can inspect the waveform there.
|
you can inspect the waveform there.
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
pub fn set_scope_buffers(&mut self, buf: [UnsyncFloatBuf; 3]) {
|
pub fn set_scope_handle(&mut self, handle: Arc<ScopeHandle>) {
|
||||||
self.buf = buf;
|
self.handle = handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,23 +53,25 @@ impl DspNode for Scope {
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut T,
|
ctx: &mut T,
|
||||||
_ectx: &mut NodeExecContext,
|
_ectx: &mut NodeExecContext,
|
||||||
_nctx: &NodeContext,
|
nctx: &NodeContext,
|
||||||
_atoms: &[SAtom],
|
_atoms: &[SAtom],
|
||||||
inputs: &[ProcBuf],
|
inputs: &[ProcBuf],
|
||||||
outputs: &mut [ProcBuf],
|
_outputs: &mut [ProcBuf],
|
||||||
ctx_vals: LedPhaseVals,
|
ctx_vals: LedPhaseVals,
|
||||||
) {
|
) {
|
||||||
use crate::dsp::{inp, out};
|
use crate::dsp::inp;
|
||||||
|
|
||||||
let in1 = inp::Scope::in1(inputs);
|
let in1 = inp::Scope::in1(inputs);
|
||||||
let in2 = inp::Scope::in2(inputs);
|
let in2 = inp::Scope::in2(inputs);
|
||||||
let in3 = inp::Scope::in3(inputs);
|
let in3 = inp::Scope::in3(inputs);
|
||||||
let inputs = [in1, in2, in3];
|
let inputs = [in1, in2, in3];
|
||||||
|
|
||||||
|
self.handle.set_active_from_mask(nctx.in_connected);
|
||||||
|
|
||||||
for frame in 0..ctx.nframes() {
|
for frame in 0..ctx.nframes() {
|
||||||
for (i, input) in inputs.iter().enumerate() {
|
for (i, input) in inputs.iter().enumerate() {
|
||||||
let in_val = input.read(frame);
|
let in_val = input.read(frame);
|
||||||
self.buf[i].write(self.idx, in_val);
|
self.handle.write(i, self.idx, in_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.idx = (self.idx + 1) % SCOPE_SAMPLES;
|
self.idx = (self.idx + 1) % SCOPE_SAMPLES;
|
||||||
|
|
|
@ -312,7 +312,7 @@ pub mod matrix_repr;
|
||||||
pub mod monitor;
|
pub mod monitor;
|
||||||
pub mod nodes;
|
pub mod nodes;
|
||||||
pub mod sample_lib;
|
pub mod sample_lib;
|
||||||
pub mod unsync_float_buf;
|
pub mod scope_handle;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub use cell_dir::CellDir;
|
pub use cell_dir::CellDir;
|
||||||
|
@ -324,7 +324,7 @@ pub use matrix_repr::load_patch_from_file;
|
||||||
pub use matrix_repr::save_patch_to_file;
|
pub use matrix_repr::save_patch_to_file;
|
||||||
pub use nodes::{new_node_engine, NodeConfigurator, NodeExecutor};
|
pub use nodes::{new_node_engine, NodeConfigurator, NodeExecutor};
|
||||||
pub use sample_lib::{SampleLibrary, SampleLoadError};
|
pub use sample_lib::{SampleLibrary, SampleLoadError};
|
||||||
pub use unsync_float_buf::UnsyncFloatBuf;
|
pub use scope_handle::ScopeHandle;
|
||||||
|
|
||||||
pub struct Context<'a, 'b, 'c, 'd> {
|
pub struct Context<'a, 'b, 'c, 'd> {
|
||||||
pub nframes: usize,
|
pub nframes: usize,
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub use crate::monitor::MON_SIG_CNT;
|
||||||
pub use crate::nodes::MinMaxMonitorSamples;
|
pub use crate::nodes::MinMaxMonitorSamples;
|
||||||
use crate::nodes::{NodeConfigurator, NodeGraphOrdering, NodeProg, MAX_ALLOCATED_NODES};
|
use crate::nodes::{NodeConfigurator, NodeGraphOrdering, NodeProg, MAX_ALLOCATED_NODES};
|
||||||
pub use crate::CellDir;
|
pub use crate::CellDir;
|
||||||
use crate::UnsyncFloatBuf;
|
use crate::ScopeHandle;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
@ -582,8 +582,8 @@ impl Matrix {
|
||||||
self.config.get_pattern_data(tracker_id)
|
self.config.get_pattern_data(tracker_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_scope_buffers(&self, scope: usize) -> Option<[UnsyncFloatBuf; 3]> {
|
pub fn get_scope_handle(&self, scope: usize) -> Option<Arc<ScopeHandle>> {
|
||||||
self.config.get_scope_buffers(scope)
|
self.config.get_scope_handle(scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if pattern data updates need to be sent to the
|
/// Checks if pattern data updates need to be sent to the
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
FeedbackFilter, GraphMessage, NodeOp, NodeProg, MAX_ALLOCATED_NODES, MAX_AVAIL_TRACKERS,
|
FeedbackFilter, GraphMessage, NodeOp, NodeProg, MAX_ALLOCATED_NODES, MAX_AVAIL_TRACKERS,
|
||||||
MAX_INPUTS, MAX_SCOPES, SCOPE_SAMPLES, UNUSED_MONITOR_IDX,
|
MAX_INPUTS, MAX_SCOPES, UNUSED_MONITOR_IDX,
|
||||||
};
|
};
|
||||||
use crate::dsp::tracker::{PatternData, Tracker};
|
use crate::dsp::tracker::{PatternData, Tracker};
|
||||||
use crate::dsp::{node_factory, Node, NodeId, NodeInfo, ParamId, SAtom};
|
use crate::dsp::{node_factory, Node, NodeId, NodeInfo, ParamId, SAtom};
|
||||||
use crate::monitor::{new_monitor_processor, MinMaxMonitorSamples, Monitor, MON_SIG_CNT};
|
use crate::monitor::{new_monitor_processor, MinMaxMonitorSamples, Monitor, MON_SIG_CNT};
|
||||||
use crate::nodes::drop_thread::DropThread;
|
use crate::nodes::drop_thread::DropThread;
|
||||||
use crate::unsync_float_buf::UnsyncFloatBuf;
|
|
||||||
use crate::util::AtomicFloat;
|
use crate::util::AtomicFloat;
|
||||||
use crate::SampleLibrary;
|
use crate::SampleLibrary;
|
||||||
|
use crate::ScopeHandle;
|
||||||
|
|
||||||
use ringbuf::{Producer, RingBuffer};
|
use ringbuf::{Producer, RingBuffer};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -179,7 +179,7 @@ pub struct NodeConfigurator {
|
||||||
/// Holding the tracker sequencers
|
/// Holding the tracker sequencers
|
||||||
pub(crate) trackers: Vec<Tracker>,
|
pub(crate) trackers: Vec<Tracker>,
|
||||||
/// Holding the scope buffers:
|
/// Holding the scope buffers:
|
||||||
pub(crate) scopes: Vec<[UnsyncFloatBuf; 3]>,
|
pub(crate) scopes: Vec<Arc<ScopeHandle>>,
|
||||||
/// The shared parts of the [NodeConfigurator]
|
/// The shared parts of the [NodeConfigurator]
|
||||||
/// and the [crate::nodes::NodeExecutor].
|
/// and the [crate::nodes::NodeExecutor].
|
||||||
pub(crate) shared: SharedNodeConf,
|
pub(crate) shared: SharedNodeConf,
|
||||||
|
@ -266,6 +266,9 @@ impl NodeConfigurator {
|
||||||
|
|
||||||
let (shared, shared_exec) = SharedNodeConf::new();
|
let (shared, shared_exec) = SharedNodeConf::new();
|
||||||
|
|
||||||
|
let mut scopes = vec![];
|
||||||
|
scopes.resize_with(MAX_SCOPES, || ScopeHandle::new_shared());
|
||||||
|
|
||||||
(
|
(
|
||||||
NodeConfigurator {
|
NodeConfigurator {
|
||||||
nodes,
|
nodes,
|
||||||
|
@ -282,14 +285,7 @@ impl NodeConfigurator {
|
||||||
atom_values: std::collections::HashMap::new(),
|
atom_values: std::collections::HashMap::new(),
|
||||||
node2idx: HashMap::new(),
|
node2idx: HashMap::new(),
|
||||||
trackers: vec![Tracker::new(); MAX_AVAIL_TRACKERS],
|
trackers: vec![Tracker::new(); MAX_AVAIL_TRACKERS],
|
||||||
scopes: vec![
|
scopes,
|
||||||
[
|
|
||||||
UnsyncFloatBuf::new_with_len(SCOPE_SAMPLES),
|
|
||||||
UnsyncFloatBuf::new_with_len(SCOPE_SAMPLES),
|
|
||||||
UnsyncFloatBuf::new_with_len(SCOPE_SAMPLES)
|
|
||||||
];
|
|
||||||
MAX_SCOPES
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
shared_exec,
|
shared_exec,
|
||||||
)
|
)
|
||||||
|
@ -649,7 +645,7 @@ impl NodeConfigurator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_scope_buffers(&self, scope: usize) -> Option<[UnsyncFloatBuf; 3]> {
|
pub fn get_scope_handle(&self, scope: usize) -> Option<Arc<ScopeHandle>> {
|
||||||
self.scopes.get(scope).cloned()
|
self.scopes.get(scope).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,8 +689,8 @@ impl NodeConfigurator {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Node::Scope { node } = &mut node {
|
if let Node::Scope { node } = &mut node {
|
||||||
if let Some(buf) = self.scopes.get(ni.instance()) {
|
if let Some(handle) = self.scopes.get(ni.instance()) {
|
||||||
node.set_scope_buffers(buf.clone());
|
node.set_scope_handle(handle.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
51
src/scope_handle.rs
Normal file
51
src/scope_handle.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) 2022 Weird Constructor <weirdconstructor@gmail.com>
|
||||||
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
|
use crate::nodes::SCOPE_SAMPLES;
|
||||||
|
use crate::util::AtomicFloat;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ScopeHandle {
|
||||||
|
bufs: [Vec<AtomicFloat>; 3],
|
||||||
|
active: [AtomicBool; 3],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScopeHandle {
|
||||||
|
pub fn new_shared() -> Arc<Self> {
|
||||||
|
let mut v1 = vec![];
|
||||||
|
v1.resize_with(SCOPE_SAMPLES, || AtomicFloat::new(0.0));
|
||||||
|
let mut v2 = vec![];
|
||||||
|
v2.resize_with(SCOPE_SAMPLES, || AtomicFloat::new(0.0));
|
||||||
|
let mut v3 = vec![];
|
||||||
|
v3.resize_with(SCOPE_SAMPLES, || AtomicFloat::new(0.0));
|
||||||
|
Arc::new(Self {
|
||||||
|
bufs: [v1, v2, v3],
|
||||||
|
active: [AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false)],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(&self, buf_idx: usize, idx: usize, v: f32) {
|
||||||
|
self.bufs[buf_idx % 3][idx % SCOPE_SAMPLES].set(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&self, buf_idx: usize, idx: usize) -> f32 {
|
||||||
|
self.bufs[buf_idx % 3][idx % SCOPE_SAMPLES].get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_active_from_mask(&self, mask: u64) {
|
||||||
|
self.active[0].store(mask & 0x1 > 0x0, Ordering::Relaxed);
|
||||||
|
self.active[1].store(mask & 0x2 > 0x0, Ordering::Relaxed);
|
||||||
|
self.active[2].store(mask & 0x4 > 0x0, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_active(&self, idx: usize) -> bool {
|
||||||
|
self.active[idx % 3].load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
SCOPE_SAMPLES
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,149 +0,0 @@
|
||||||
// Copyright (c) 2022 Weird Constructor <weirdconstructor@gmail.com>
|
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
|
||||||
// See README.md and COPYING for details.
|
|
||||||
|
|
||||||
use crate::util::AtomicFloat;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
/// A float buffer that can be written to and read from in an unsynchronized manner.
|
|
||||||
///
|
|
||||||
/// One use case is writing samples to this buffer in the audio thread while
|
|
||||||
/// a GUI thread reads from this buffer. Mostly useful for an oscilloscope.
|
|
||||||
///
|
|
||||||
///```
|
|
||||||
/// use hexodsp::UnsyncFloatBuf;
|
|
||||||
///
|
|
||||||
/// let handle1 = UnsyncFloatBuf::new_with_len(10);
|
|
||||||
/// let handle2 = handle1.clone();
|
|
||||||
///
|
|
||||||
/// std::thread::spawn(move || {
|
|
||||||
/// handle1.write(9, 2032.0);
|
|
||||||
/// }).join().unwrap();
|
|
||||||
///
|
|
||||||
/// std::thread::spawn(move || {
|
|
||||||
/// assert_eq!(handle2.read(9), 2032.0);
|
|
||||||
/// assert_eq!(handle2.read(20), 0.0); // out of range!
|
|
||||||
/// }).join().unwrap();
|
|
||||||
///```
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct UnsyncFloatBuf(Arc<UnsyncFloatBufImpl>);
|
|
||||||
|
|
||||||
impl UnsyncFloatBuf {
|
|
||||||
/// Creates a new unsynchronized float buffer with the given length.
|
|
||||||
pub fn new_with_len(len: usize) -> Self {
|
|
||||||
Self(UnsyncFloatBufImpl::new_shared(len))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write float to the given index.
|
|
||||||
///
|
|
||||||
/// If index is out of range, nothing will be written.
|
|
||||||
pub fn write(&self, idx: usize, v: f32) {
|
|
||||||
self.0.write(idx, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a float from the given index.
|
|
||||||
///
|
|
||||||
/// If index is out of range, 0.0 will be returned.
|
|
||||||
pub fn read(&self, idx: usize) -> f32 {
|
|
||||||
self.0.read(idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Length of the buffer.
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.0.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Private implementation detail for [UnsyncFloatBuf].
|
|
||||||
///
|
|
||||||
/// This mostly allows [UnsyncFloatBuf] to wrap UnsyncFloatBufImpl into an [std::sync::Arc],
|
|
||||||
/// to make sure the `data_store` Vector is not moved accidentally.
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct UnsyncFloatBufImpl {
|
|
||||||
data_store: Vec<AtomicFloat>,
|
|
||||||
len: usize,
|
|
||||||
ptr: *mut AtomicFloat,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Sync for UnsyncFloatBuf {}
|
|
||||||
unsafe impl Send for UnsyncFloatBuf {}
|
|
||||||
|
|
||||||
impl UnsyncFloatBufImpl {
|
|
||||||
/// Create a new shared reference of this. You must not create
|
|
||||||
/// an UnsyncFloatBufImpl that can move! Otherwise the internal pointer
|
|
||||||
/// would be invalidated.
|
|
||||||
fn new_shared(len: usize) -> Arc<Self> {
|
|
||||||
let mut rc = Arc::new(Self { data_store: Vec::new(), len, ptr: std::ptr::null_mut() });
|
|
||||||
|
|
||||||
let mut unsync_buf = Arc::get_mut(&mut rc).expect("No other reference to this Arc");
|
|
||||||
unsync_buf.data_store.resize_with(len, || AtomicFloat::new(0.0));
|
|
||||||
|
|
||||||
// XXX: Taking the pointer to the Vec data buffer is fine,
|
|
||||||
// because it will not be moved when inside the Arc.
|
|
||||||
unsync_buf.ptr = unsync_buf.data_store.as_mut_ptr();
|
|
||||||
|
|
||||||
rc
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write a sample.
|
|
||||||
fn write(&self, idx: usize, v: f32) {
|
|
||||||
if idx < self.len {
|
|
||||||
unsafe {
|
|
||||||
(*self.ptr.add(idx)).set(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read a sample.
|
|
||||||
fn read(&self, idx: usize) -> f32 {
|
|
||||||
if idx < self.len {
|
|
||||||
unsafe { (*self.ptr.add(idx)).get() }
|
|
||||||
} else {
|
|
||||||
0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the length of this buffer.
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
self.len
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn check_unsync_float_buf_working() {
|
|
||||||
let handle1 = UnsyncFloatBuf::new_with_len(512);
|
|
||||||
for i in 0..512 {
|
|
||||||
handle1.write(i, i as f32);
|
|
||||||
}
|
|
||||||
let handle2 = handle1.clone();
|
|
||||||
for i in 0..512 {
|
|
||||||
assert_eq!(handle2.read(i), i as f32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn check_unsync_float_buf_thread() {
|
|
||||||
let handle1 = UnsyncFloatBuf::new_with_len(512);
|
|
||||||
let handle2 = handle1.clone();
|
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
for i in 0..512 {
|
|
||||||
handle1.write(i, i as f32);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.join()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
for i in 0..512 {
|
|
||||||
assert_eq!(handle2.read(i), i as f32);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.join()
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,22 +26,22 @@ fn check_node_scope_1() {
|
||||||
matrix.set_param(in3_p, SAtom::param(1.0));
|
matrix.set_param(in3_p, SAtom::param(1.0));
|
||||||
let _res = run_for_ms(&mut node_exec, 11.0);
|
let _res = run_for_ms(&mut node_exec, 11.0);
|
||||||
|
|
||||||
let scope = matrix.get_scope_buffers(0).unwrap();
|
let scope = matrix.get_scope_handle(0).unwrap();
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
for x in 0..SCOPE_SAMPLES {
|
for x in 0..SCOPE_SAMPLES {
|
||||||
v.push(scope[0].read(x));
|
v.push(scope.read(0, x));
|
||||||
}
|
}
|
||||||
assert_decimated_feq!(v, 80, vec![0.0022, 0.1836, 0.3650, 0.5464, 0.7278, 0.9093, 1.0]);
|
assert_decimated_feq!(v, 80, vec![0.0022, 0.1836, 0.3650, 0.5464, 0.7278, 0.9093, 1.0]);
|
||||||
|
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
for x in 0..SCOPE_SAMPLES {
|
for x in 0..SCOPE_SAMPLES {
|
||||||
v.push(scope[1].read(x));
|
v.push(scope.read(1, x));
|
||||||
}
|
}
|
||||||
assert_decimated_feq!(v, 80, vec![0.0022, 0.1836, 0.3650, 0.5464, 0.7278, 0.9093, 1.0]);
|
assert_decimated_feq!(v, 80, vec![0.0022, 0.1836, 0.3650, 0.5464, 0.7278, 0.9093, 1.0]);
|
||||||
|
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
for x in 0..SCOPE_SAMPLES {
|
for x in 0..SCOPE_SAMPLES {
|
||||||
v.push(scope[2].read(x));
|
v.push(scope.read(2, x));
|
||||||
}
|
}
|
||||||
assert_decimated_feq!(v, 80, vec![0.0022, 0.1836, 0.3650, 0.5464, 0.7278, 0.9093, 1.0]);
|
assert_decimated_feq!(v, 80, vec![0.0022, 0.1836, 0.3650, 0.5464, 0.7278, 0.9093, 1.0]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue