diff --git a/src/audio/callback.rs b/src/audio/callback.rs index 2ed5422..5371b66 100644 --- a/src/audio/callback.rs +++ b/src/audio/callback.rs @@ -40,12 +40,11 @@ pub fn get_callback( let r = data[1][i]; let m = (l + r) / 2.0; let s = (l - r) / 2.0; - buf.raw.l.push(l); - buf.raw.r.push(r); - buf.raw.m.push(m); - buf.raw.s.push(s); - - let raw_len = buf.raw.l.len(); + // buf.raw.l.push(l); + // buf.raw.r.push(r); + // buf.raw.m.push(m); + // buf.raw.s.push(s); + // let raw_len = buf.raw.l.len(); if spectrum_on { if buf.spectrum.ab { @@ -141,11 +140,83 @@ pub fn get_callback( if oscilloscope_on { // Oscilloscope - if raw_len >= 2400 { - send_data.oscilloscope = OscilloscopeSendData { - len: 2400, - data: buf.raw.m[raw_len - 2400..raw_len].to_vec(), - }; + if buf.setting.oscilloscope.follow_pitch { + match buf.setting.oscilloscope.cycle { + OscilloscopeCycle::Multi => { + if buf.osc.last.is_none() { + if m > 0.0 { + buf.osc.raw.push(m); + buf.osc.last = Some(m); + } + } else { + let last_times_m = buf.osc.last.unwrap() * m; + if last_times_m > 0.0 { + buf.osc.raw.push(m); + buf.osc.last = Some(m); + } else if last_times_m == 0.0 { + buf.osc.raw.push(m); + } else if last_times_m < 0.0 { + buf.osc.raw.push(m); + buf.osc.last = Some(m); + buf.osc.even_trun = !buf.osc.even_trun; + } + } + if buf.osc.raw.len() >= 2400 && buf.osc.even_trun { + send_data.oscilloscope = OscilloscopeSendData { + len: buf.osc.raw.len(), + data: buf.osc.raw.clone(), + }; + buf.osc.clear(); + } + } + OscilloscopeCycle::Single => { + if buf.osc.last.is_none() { + if m > 0.0 { + buf.osc.raw.push(m); + buf.osc.last = Some(m); + } + } else { + let last_times_m = buf.osc.last.unwrap() * m; + if last_times_m > 0.0 { + buf.osc.raw.push(m); + buf.osc.last = Some(m); + } else if last_times_m == 0.0 { + buf.osc.raw.push(m); + } else if last_times_m < 0.0 { + buf.osc.raw.push(m); + buf.osc.last = Some(m); + if buf.osc.even_trun { + buf.osc.first_turn = true; + } + buf.osc.even_trun = !buf.osc.even_trun; + } + } + if buf.osc.first_turn && buf.osc.even_trun { + send_data.oscilloscope = OscilloscopeSendData { + len: buf.osc.raw.len(), + data: buf.osc.raw.clone(), + }; + buf.osc.clear(); + } + } + } + // in case of buffer overflow + if buf.osc.raw.len() >= 4096 { + send_data.oscilloscope = OscilloscopeSendData { + len: buf.osc.raw.len(), + data: buf.osc.raw.clone(), + }; + buf.osc.clear(); + } + } else { + buf.osc.raw.push(m); + if buf.osc.raw.len() >= 2400 { + send_data.oscilloscope = OscilloscopeSendData { + len: 2400, + data: buf.osc.raw.clone(), + }; + buf.osc.clear(); + } } } @@ -320,9 +391,9 @@ pub fn get_callback( } } - if raw_len >= 8192 { - buf.raw.keep_last(4096); - } + // if raw_len >= 8192 { + // buf.raw.keep_last(4096); + // } } // Send data diff --git a/src/frame/oscilloscope_meter.rs b/src/frame/oscilloscope_meter.rs index b15c555..1a68861 100644 --- a/src/frame/oscilloscope_meter.rs +++ b/src/frame/oscilloscope_meter.rs @@ -12,31 +12,30 @@ impl NanometersApp { ) { ui.painter().rect_filled(rect, 0.0, self.setting.theme.bg); if data.data.is_empty() { - ui.painter().add(Shape::line( - self.oscilloscope.plot.clone(), + ui.painter().extend(self.oscilloscope.plot.clone()); + } else { + let len = data.len; + let mut lines = vec![]; + let points: Vec = (0..len) + .map(|i| { + let w = rect.width() / (len as f32 - 1.0); + let x = rect.min.x + w * i as f32; + let y = (1.0 - data.data.get(i).unwrap_or(&0.0)) * rect.center().y; + if self.setting.oscilloscope.shadow { + lines.push(Shape::line_segment( + [pos2(x, rect.center().y), pos2(x, y)], + Stroke::new(w, self.setting.theme.main.gamma_multiply(0.5)), + )); + } + pos2(x, y) + }) + .collect(); + lines.push(Shape::line( + points, Stroke::new(2.0, self.setting.theme.main), )); - } else { - if self.setting.oscilloscope.follow_pitch { - } else { - let points: Vec = (0..2400) - .map(|i| { - let x = rect.min.x + rect.width() * i as f32 / 2400.0; - let y = (1.0 - - data - .data - .get(data.data.len().saturating_sub(2400) + i) - .unwrap_or(&0.0)) - * rect.center().y; - pos2(x, y) - }) - .collect(); - self.oscilloscope.plot = points.clone(); - ui.painter().add(Shape::line( - points, - Stroke::new(2.0, self.setting.theme.main), - )); - } + self.oscilloscope.plot = lines.clone(); + ui.painter().extend(lines); } } } diff --git a/src/frame/setting_panel.rs b/src/frame/setting_panel.rs index aa895cb..bb8feff 100644 --- a/src/frame/setting_panel.rs +++ b/src/frame/setting_panel.rs @@ -229,21 +229,48 @@ impl NanometersApp { ui.heading("Oscilloscope"); ui.horizontal(|ui| { ui.label("Follow Pitch"); - ui.selectable_value(&mut self.setting.oscilloscope.follow_pitch, true, "On"); - ui.selectable_value(&mut self.setting.oscilloscope.follow_pitch, false, "Off"); + if ui + .selectable_value(&mut self.setting.oscilloscope.follow_pitch, true, "On") + .changed() + { + self.tx_setting.as_ref().unwrap().send(self.setting.clone()); + }; + if ui + .selectable_value(&mut self.setting.oscilloscope.follow_pitch, false, "Off") + .changed() + { + self.tx_setting.as_ref().unwrap().send(self.setting.clone()); + }; }); + if self.setting.oscilloscope.follow_pitch { + ui.horizontal(|ui| { + ui.label("Cycle"); + if ui + .selectable_value( + &mut self.setting.oscilloscope.cycle, + setting::OscilloscopeCycle::Multi, + "Multi", + ) + .changed() + { + self.tx_setting.as_ref().unwrap().send(self.setting.clone()); + }; + if ui + .selectable_value( + &mut self.setting.oscilloscope.cycle, + setting::OscilloscopeCycle::Single, + "Single", + ) + .changed() + { + self.tx_setting.as_ref().unwrap().send(self.setting.clone()); + }; + }); + }; ui.horizontal(|ui| { - ui.label("Cycle"); - ui.selectable_value( - &mut self.setting.oscilloscope.cycle, - setting::OscilloscopeCycle::Multi, - "Multi", - ); - ui.selectable_value( - &mut self.setting.oscilloscope.cycle, - setting::OscilloscopeCycle::Single, - "Single", - ); + ui.label("Shadow"); + ui.selectable_value(&mut self.setting.oscilloscope.shadow, true, "On"); + ui.selectable_value(&mut self.setting.oscilloscope.shadow, false, "Off"); }); }); }); diff --git a/src/frame/waveform_meter.rs b/src/frame/waveform_meter.rs index a758069..581b0fe 100644 --- a/src/frame/waveform_meter.rs +++ b/src/frame/waveform_meter.rs @@ -184,18 +184,19 @@ impl NanometersApp { self.waveform.plot_point.g.pop_front(); self.waveform.plot_point.b.pop_front(); } + self.waveform .plot_point .r - .push_back(rect.height() * (1.0 - (v.color.r() / 255) as f32)); + .push_back(rect.height() * (1.0 - v.color.r() as f32 / 255.0)); self.waveform .plot_point .g - .push_back(rect.height() * (1.0 - (v.color.g() / 255) as f32)); + .push_back(rect.height() * (1.0 - v.color.g() as f32 / 255.0)); self.waveform .plot_point .b - .push_back(rect.height() * (1.0 - (v.color.b() / 255) as f32)); + .push_back(rect.height() * (1.0 - v.color.b() as f32 / 255.0)); }); } let len = self.waveform.plot_point.r.len(); diff --git a/src/setting/oscilloscope.rs b/src/setting/oscilloscope.rs index 5774179..2c9a506 100644 --- a/src/setting/oscilloscope.rs +++ b/src/setting/oscilloscope.rs @@ -12,10 +12,50 @@ pub enum OscilloscopeCycle { pub struct OscilloscopeSetting { pub(crate) follow_pitch: bool, pub(crate) cycle: OscilloscopeCycle, + pub(crate) shadow: bool, } #[derive(Default, Clone, Debug, Serialize, Deserialize)] pub struct Oscilloscope { #[serde(skip)] - pub(crate) plot: Vec, + pub(crate) plot: Vec, +} + +#[derive(Debug, Clone, Default)] +pub struct OscCalcBuffer { + pub even_trun: bool, + pub first_turn: bool, + pub raw: Vec, + pub last: Option, +} + +impl OscCalcBuffer { + pub fn new() -> Self { + Self { + even_trun: false, + first_turn: false, + raw: Vec::new(), + last: None, + } + } + pub fn clear(&mut self) { + self.even_trun = false; + self.first_turn = false; + self.raw.clear(); + self.last = None; + } +} + +#[derive(Debug, Clone, Default)] +pub struct OscilloscopeSendData { + pub len: usize, + pub data: Vec, +} + +impl OscilloscopeSendData { + pub fn new() -> Self { + Self { + ..Default::default() + } + } } diff --git a/src/setting/waveform.rs b/src/setting/waveform.rs index 29f970c..c228208 100644 --- a/src/setting/waveform.rs +++ b/src/setting/waveform.rs @@ -210,6 +210,7 @@ pub struct WaveformSendData { pub r: Vec, pub m: Vec, pub s: Vec, + // pub history: Vec, } impl WaveformSendData { diff --git a/src/utils/data_struct.rs b/src/utils/data_struct.rs index d803fe7..a7af18f 100644 --- a/src/utils/data_struct.rs +++ b/src/utils/data_struct.rs @@ -267,6 +267,7 @@ pub struct AudioSourceBuffer { pub vector: VectorscopeCalcBuffer, pub spectrogram: SpectrogramCalcBuffer, pub spectrum: SpectrumCalcBuffer, + pub osc: OscCalcBuffer, pub setting: Setting, } @@ -312,20 +313,6 @@ impl SpectrumSendData { } } -#[derive(Debug, Clone, Default)] -pub struct OscilloscopeSendData { - pub len: usize, - pub data: Vec, -} - -impl OscilloscopeSendData { - pub fn new() -> Self { - Self { - ..Default::default() - } - } -} - #[derive(Debug, Clone, Default)] pub struct SendData { pub waveform: WaveformSendData,