Skip to content

Commit a50b852

Browse files
committed
use ArrayRef as much as possible instead of ArrayView, ArrayViewMut
1 parent 9a55737 commit a50b852

File tree

11 files changed

+53
-60
lines changed

11 files changed

+53
-60
lines changed

src-tauri/src/core/audio.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ impl Audio {
5353
stat_calculator: &mut StatCalculator,
5454
guard_clipping_mode: GuardClippingMode,
5555
) where
56-
F: Fn(ArrayViewMut2<f32>),
56+
F: Fn(&mut ArrayRef2<f32>),
5757
{
58-
f(self.wavs.view_mut());
58+
f(&mut self.wavs);
5959
let guard_clip_result = self.guard_clipping(guard_clipping_mode);
6060
self.guard_clip_stats = (&guard_clip_result).into();
6161
self.guard_clip_result = guard_clip_result;
@@ -168,7 +168,7 @@ impl GuardClipping<Ix2> for Audio {
168168
let gain_seq = if peak > 1. {
169169
let gain_seq = LIMITER_MANAGER.with_borrow_mut(|manager| {
170170
let limiter = manager.get_or_insert(self.sr);
171-
limiter.process_inplace(self.wavs.view_mut())
171+
limiter.process_inplace(&mut self.wavs)
172172
});
173173
gain_seq.into_shape_with_order(gain_shape).unwrap()
174174
} else {

src-tauri/src/core/dynamics/decibel.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ where
2727
A: Float + MaybeNan,
2828
<A as MaybeNan>::NotNan: Ord,
2929
{
30-
fn into_value<D: Dimension>(self, data_for_max: ArrayView<A, D>) -> A {
30+
fn into_value<D: Dimension>(self, data_for_max: &ArrayRef<A, D>) -> A {
3131
match self {
3232
DeciBelRef::Value(v) => {
3333
debug_assert!(v.is_sign_positive());
@@ -66,7 +66,7 @@ where
6666
fn log_for_dB(&self, reference: DeciBelRef<Self::A>, amin: Self::A) -> Self {
6767
debug_assert!(amin.is_sign_positive());
6868
let temp = [*self];
69-
let ref_value = reference.into_value(temp[..].into());
69+
let ref_value = reference.into_value(&ArrayView1::from(&temp[..]));
7070
if ref_value.is_nan() || ref_value.is_sign_negative() {
7171
return A::nan();
7272
}
@@ -169,7 +169,7 @@ where
169169
type A = A;
170170
fn log_for_dB_inplace(&mut self, reference: DeciBelRef<A>, amin: A) {
171171
debug_assert!(amin.is_sign_positive());
172-
let ref_value = reference.into_value(self.view());
172+
let ref_value = reference.into_value(self);
173173
if ref_value.is_nan() {
174174
return;
175175
} else if ref_value.is_sign_negative() {

src-tauri/src/core/dynamics/limiter.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ impl PerfectLimiter {
8989
}
9090

9191
/// process one sample, and returns (delayed_output, gain)
92-
pub fn _step(&mut self, frame: ArrayView1<f32>) -> (Array1<f32>, f32) {
92+
pub fn _step(&mut self, frame: &ArrayRef1<f32>) -> (Array1<f32>, f32) {
9393
let mut delayed = self.buffer.slice(s![self.i_buf, ..]).to_owned();
9494
let gain = self.calc_gain(frame);
95-
azip!((y in &mut self.buffer.slice_mut(s![self.i_buf, ..]), x in &frame) *y = *x as f64);
95+
azip!((y in &mut self.buffer.slice_mut(s![self.i_buf, ..]), x in frame) *y = *x as f64);
9696
self.i_buf = (self.i_buf + 1) % self.buffer.shape()[0];
9797
// println!("i={} d={} g={}", value, delayed, gain);
9898
delayed *= gain;
@@ -107,7 +107,7 @@ impl PerfectLimiter {
107107
}
108108

109109
/// apply limiter to wav inplace , return gain array. parallel over channel axis (=Axis(0))
110-
pub fn process_inplace(&mut self, mut wavs: ArrayViewMut2<f32>) -> Array1<f32> {
110+
pub fn process_inplace(&mut self, wavs: &mut ArrayRef2<f32>) -> Array1<f32> {
111111
self.reset(0);
112112

113113
let zero = Array1::zeros(wavs.shape()[0]);
@@ -116,7 +116,7 @@ impl PerfectLimiter {
116116
wavs.lanes(Axis(0)),
117117
itertools::repeat_n(zero.view(), attack),
118118
)
119-
.map(|x| self.calc_gain(x))
119+
.map(|x| self.calc_gain(&x))
120120
.skip(attack)
121121
.collect();
122122

@@ -136,13 +136,13 @@ impl PerfectLimiter {
136136

137137
/// apply limiter to wav, return (output, gain array)
138138
#[inline]
139-
pub fn _process(&mut self, wavs: ArrayView2<f32>) -> (Array2<f32>, Array1<f32>) {
139+
pub fn _process(&mut self, wavs: &ArrayRef2<f32>) -> (Array2<f32>, Array1<f32>) {
140140
let mut out = wavs.to_owned();
141-
let gain_seq = self.process_inplace(out.view_mut());
141+
let gain_seq = self.process_inplace(&mut out);
142142
(out, gain_seq)
143143
}
144144

145-
fn calc_gain(&mut self, frame: ArrayView1<f32>) -> f64 {
145+
fn calc_gain(&mut self, frame: &ArrayRef1<f32>) -> f64 {
146146
// max abs over all channels
147147
let v_abs = frame.iter().map(|x| x.abs()).reduce(f32::max).unwrap() as f64;
148148
let raw_gain = if v_abs > self.threshold {
@@ -208,7 +208,7 @@ impl SimpleLimiter {
208208
}
209209
}
210210

211-
pub fn process_inplace(&mut self, mut wav: ArrayViewMut1<f32>) {
211+
pub fn process_inplace(&mut self, wav: &mut ArrayRef1<f32>) {
212212
let mut delay_index = 0;
213213
let mut gain = 1.;
214214
let mut envelope = 0.;
@@ -236,9 +236,9 @@ impl SimpleLimiter {
236236
}
237237
}
238238

239-
pub fn process(&mut self, wav: ArrayView1<f32>) -> Array1<f32> {
239+
pub fn process(&mut self, wav: &ArrayRef1<f32>) -> Array1<f32> {
240240
let mut out = wav.to_owned();
241-
self.process_inplace(out.view_mut());
241+
self.process_inplace(&mut out);
242242
out
243243
}
244244
}
@@ -268,7 +268,7 @@ mod tests {
268268
let (mut wavs, format_info) = open_audio_file(path).unwrap();
269269
let mut limiter = PerfectLimiter::new(format_info.sr, 1., 5., 15., 40.);
270270
wavs *= 8.;
271-
let gain_seq = limiter.process_inplace(wavs.view_mut());
271+
let gain_seq = limiter.process_inplace(&mut wavs);
272272
assert!(
273273
gain_seq.iter().all(|x| (0.0..=1.0).contains(x)),
274274
"cnt of gain>1: {}, cnt of gain<0: {}",

src-tauri/src/core/dynamics/stats.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::fmt::{self, Display};
22

33
use ebur128::{EbuR128, Mode as LoudnessMode};
4+
use ndarray::RemoveAxis;
45
use ndarray::prelude::*;
5-
use ndarray::{Data, RemoveAxis};
66
use ndarray_stats::MaybeNan;
77
use num_traits::{AsPrimitive, Float};
88
use rayon::prelude::*;
@@ -71,9 +71,8 @@ pub trait MaxPeak<A> {
7171
fn max_peak(&self) -> A;
7272
}
7373

74-
impl<S, D> MaxPeak<f64> for ArrayBase<S, D>
74+
impl<D> MaxPeak<f64> for ArrayRef<f64, D>
7575
where
76-
S: Data<Elem = f64>,
7776
D: Dimension,
7877
{
7978
fn max_peak(&self) -> f64 {
@@ -82,9 +81,8 @@ where
8281
}
8382
}
8483

85-
impl<S, D> MaxPeak<f32> for ArrayBase<S, D>
84+
impl<D> MaxPeak<f32> for ArrayRef<f32, D>
8685
where
87-
S: Data<Elem = f32>,
8886
D: Dimension,
8987
{
9088
fn max_peak(&self) -> f32 {
@@ -116,11 +114,11 @@ impl Display for GuardClippingStats {
116114
}
117115

118116
impl GuardClippingStats {
119-
pub fn from_wav_before_clip<'a, A, D>(wav_before_clip: ArrayView<'a, A, D>) -> Self
117+
pub fn from_wav_before_clip<A, D>(wav_before_clip: &ArrayRef<A, D>) -> Self
120118
where
121119
A: Float + AsPrimitive<f32> + DeciBel,
122120
D: Dimension,
123-
ArrayView<'a, A, D>: MaxPeak<A>,
121+
ArrayRef<A, D>: MaxPeak<A>,
124122
{
125123
let max_peak = wav_before_clip.max_peak();
126124
if max_peak > A::one() {
@@ -143,13 +141,12 @@ impl GuardClippingStats {
143141
}
144142
}
145143

146-
pub fn from_gain_seq<'a, A, S, D>(gain_seq: ArrayView<'a, A, D>) -> Self
144+
pub fn from_gain_seq<A, D>(gain_seq: &ArrayRef<A, D>) -> Self
147145
where
148146
A: Float + MaybeNan + DeciBel + AsPrimitive<f32>,
149147
<A as MaybeNan>::NotNan: Ord,
150-
S: Data<Elem = A>,
151148
D: Dimension,
152-
ArrayView<'a, A, D>: MinSIMD<A, S, D>,
149+
ArrayRef<A, D>: MinSIMD<A, D>,
153150
{
154151
GuardClippingStats {
155152
max_reduction_gain_dB: gain_seq.min_simd().dB_from_amp_default().as_(),
@@ -168,7 +165,7 @@ impl<D: Dimension + RemoveAxis> From<&GuardClippingResult<D>>
168165
let vec = before_clip
169166
.axis_iter(Axis(0))
170167
.into_par_iter()
171-
.map(GuardClippingStats::from_wav_before_clip)
168+
.map(|x| GuardClippingStats::from_wav_before_clip(&x))
172169
.collect();
173170
Array::from_shape_vec(raw_dim.remove_axis(Axis(raw_dim.ndim() - 1)), vec).unwrap()
174171
}
@@ -181,7 +178,7 @@ impl<D: Dimension + RemoveAxis> From<&GuardClippingResult<D>>
181178
let vec = gain_seq
182179
.axis_iter(Axis(0))
183180
.into_par_iter()
184-
.map(GuardClippingStats::from_gain_seq)
181+
.map(|x| GuardClippingStats::from_gain_seq(&x))
185182
.collect();
186183
Array::from_shape_vec(raw_dim.remove_axis(Axis(raw_dim.ndim() - 1)), vec).unwrap()
187184
}

src-tauri/src/core/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ impl TrackManager {
152152
.par_extend(id_ch_tuples.into_par_iter().map(|(id, ch)| {
153153
let track = &tracklist[id];
154154
let spec = self.spec_analyzer.calc_spec(
155-
track.channel(ch),
155+
&track.channel(ch),
156156
track.sr(),
157157
&self.setting,
158158
parallel,
@@ -211,7 +211,7 @@ impl TrackManager {
211211
spec.shape()[1],
212212
);
213213
let spec_img = visualize::convert_spectrogram_to_img(
214-
spec.view(),
214+
spec,
215215
i_freq_range,
216216
(self.min_dB, self.max_dB),
217217
Some(self.colormap_length),

src-tauri/src/core/simd.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::arch::is_x86_feature_detected;
88
use std::arch::x86_64::*;
99

1010
use itertools::Itertools;
11-
use ndarray::{ArrayBase, Data, DataMut, Dimension};
11+
use ndarray::{ArrayBase, ArrayRef, DataMut, Dimension};
1212
use ndarray_stats::QuantileExt;
1313

1414
pub fn find_min_max(slice: &[f32]) -> (f32, f32) {
@@ -55,27 +55,24 @@ pub fn find_min(slice: &[f32]) -> f32 {
5555
find_min_scalar(slice)
5656
}
5757

58-
pub trait MinSIMD<A, S, D>
58+
pub trait MinSIMD<A, D>
5959
where
60-
S: Data<Elem = A>,
6160
D: Dimension,
6261
{
6362
fn min_simd(&self) -> A;
6463
}
6564

66-
impl<S, D> MinSIMD<f32, S, D> for ArrayBase<S, D>
65+
impl<D> MinSIMD<f32, D> for ArrayRef<f32, D>
6766
where
68-
S: Data<Elem = f32>,
6967
D: Dimension,
7068
{
7169
fn min_simd(&self) -> f32 {
72-
find_min(self.as_slice_memory_order().unwrap())
70+
find_min(self.as_slice_memory_order().unwrap_or_default())
7371
}
7472
}
7573

76-
impl<S, D> MinSIMD<f64, S, D> for ArrayBase<S, D>
74+
impl<D> MinSIMD<f64, D> for ArrayRef<f64, D>
7775
where
78-
S: Data<Elem = f64>,
7976
D: Dimension,
8077
{
8178
fn min_simd(&self) -> f64 {

src-tauri/src/core/spectrogram.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl SpectrogramAnalyzer {
186186

187187
pub fn calc_spec(
188188
&self,
189-
wav: ArrayView1<f32>,
189+
wav: &ArrayRef1<f32>,
190190
sr: u32,
191191
setting: &SpecSetting,
192192
parallel: bool,

src-tauri/src/core/spectrogram/stft.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use super::super::windows::{WindowType, calc_normalized_win};
1414
use realfft::{RealFftPlanner, RealToComplex};
1515

1616
pub fn perform_stft<'a, A>(
17-
input: ArrayView1<A>,
17+
input: &ArrayRef1<A>,
1818
win_length: usize,
1919
hop_length: usize,
2020
n_fft: usize,
@@ -35,7 +35,7 @@ where
3535
let to_frames_wrapper = move |x| {
3636
let n_pad_left = (n_fft - win_length) / 2;
3737
let n_pad_right = n_fft - win_length - n_pad_left;
38-
to_windowed_frames(x, window.view(), hop_length, (n_pad_left, n_pad_right))
38+
to_windowed_frames(x, &window, hop_length, (n_pad_left, n_pad_right))
3939
};
4040

4141
let fft_module = fft_module
@@ -49,7 +49,7 @@ where
4949

5050
if input.len() < win_length {
5151
let padded = input.pad((win_length / 2, win_length / 2), Axis(0), PadMode::Reflect);
52-
let mut frames = to_frames_wrapper(padded.view());
52+
let mut frames = to_frames_wrapper(&padded);
5353

5454
let n_frames = frames.len();
5555
let mut output = Array2::<Complex<A>>::zeros((n_frames, n_fft / 2 + 1));
@@ -78,10 +78,11 @@ where
7878
input
7979
.slice(s![..(win_length - 1)])
8080
.pad((win_length / 2, 0), Axis(0), PadMode::Reflect);
81-
let mut front_frames = to_frames_wrapper(front_wav.view());
81+
let mut front_frames = to_frames_wrapper(&front_wav);
8282

8383
let mut first_i = front_frames.len() * hop_length - win_length / 2;
84-
let mut frames = to_frames_wrapper(input.slice(s![first_i..]));
84+
let mid_wav = input.slice(s![first_i..]);
85+
let mut frames = to_frames_wrapper(&mid_wav);
8586

8687
first_i += frames.len() * hop_length;
8788
let i_back_wav_start = first_i.min(input.len() - win_length / 2 - 1);
@@ -91,7 +92,7 @@ where
9192
.slice(s![i_back_wav_start..])
9293
.pad((0, win_length / 2), Axis(0), PadMode::Reflect);
9394
back_wav.slice_collapse(s![(first_i - i_back_wav_start).max(0)..]);
94-
let mut back_frames = to_frames_wrapper(back_wav.view());
95+
let mut back_frames = to_frames_wrapper(&back_wav);
9596

9697
let n_frames = front_frames.len() + frames.len() + back_frames.len();
9798
let mut output = Array2::<Complex<A>>::zeros((n_frames, n_fft / 2 + 1));
@@ -124,8 +125,8 @@ where
124125

125126
#[inline]
126127
fn to_windowed_frames<A: Float>(
127-
input: ArrayView1<A>,
128-
window: ArrayView1<A>,
128+
input: &ArrayRef1<A>,
129+
window: &ArrayRef1<A>,
129130
hop_length: usize,
130131
(n_pad_left, n_pad_right): (usize, usize),
131132
) -> Vec<Array1<A>> {
@@ -173,7 +174,7 @@ mod tests {
173174
fn stft_works() {
174175
let impulse = Array1::<f32>::impulse(4, 2);
175176
assert_eq!(
176-
perform_stft(impulse.view(), 4, 2, 4, None, None, false),
177+
perform_stft(&impulse, 4, 2, 4, None, None, false),
177178
arr2(&[
178179
[
179180
Complex::<f32>::new(0., 0.),
@@ -197,7 +198,7 @@ mod tests {
197198
#[test]
198199
fn stft_short_wav() {
199200
let impulse = Array1::<f32>::impulse(2, 1);
200-
let spec = perform_stft(impulse.view(), 8, 6, 8, None, None, false);
201+
let spec = perform_stft(&impulse, 8, 6, 8, None, None, false);
201202
dbg!(spec.shape());
202203
}
203204
}

src-tauri/src/core/utils.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::{self, Path, PathBuf};
55
use identity_hash::IntMap;
66
use itertools::Itertools;
77
use ndarray::prelude::*;
8-
use ndarray::{Data, OwnedRepr, RemoveAxis};
8+
use ndarray::{OwnedRepr, RemoveAxis};
99
use num_traits::Num;
1010

1111
pub fn unique_filenames(paths: IntMap<usize, PathBuf>) -> IntMap<usize, String> {
@@ -74,10 +74,9 @@ pub trait Pad<A> {
7474
fn pad(&self, n_pads: (usize, usize), axis: Axis, mode: PadMode<A>) -> Self::WithOwnedA;
7575
}
7676

77-
impl<A, S, D> Pad<A> for ArrayBase<S, D>
77+
impl<A, D> Pad<A> for ArrayRef<A, D>
7878
where
7979
A: Copy,
80-
S: Data<Elem = A>,
8180
D: Dimension + RemoveAxis,
8281
{
8382
type WithOwnedA = ArrayBase<OwnedRepr<A>, D>;
@@ -146,9 +145,8 @@ pub trait Planes<A> {
146145
fn planes(&self) -> Vec<&[A]>;
147146
}
148147

149-
impl<A, S, D> Planes<A> for ArrayBase<S, D>
148+
impl<A, D> Planes<A> for ArrayRef<A, D>
150149
where
151-
S: Data<Elem = A>,
152150
D: Dimension + RemoveAxis,
153151
{
154152
fn planes(&self) -> Vec<&[A]> {

src-tauri/src/core/visualize/drawing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use ndarray::prelude::*;
22

33
#[allow(non_snake_case)]
44
pub fn convert_spectrogram_to_img(
5-
spec: ArrayView2<f32>,
5+
spec: &ArrayRef2<f32>,
66
i_freq_range: (usize, usize),
77
dB_range: (f32, f32),
88
colormap_length: Option<u32>,

0 commit comments

Comments
 (0)