diff --git a/Cargo.lock b/Cargo.lock index ae069c464..ac3846ee5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,6 +568,7 @@ dependencies = [ "crossbeam-channel", "derive_more", "device_query", + "either", "enigo", "futures-timer", "helgoboss-allocator", @@ -4064,6 +4065,7 @@ dependencies = [ "static_assertions", "swell-ui", "thiserror", + "thread-priority", "tinyvec", "tokio", "tokio-stream", @@ -4786,7 +4788,7 @@ version = "0.1.0" [[package]] name = "reaper-high" version = "0.1.0" -source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#21c06e5a5ab2478352303547926d38ccbefdf171" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#9db7c4c619630eb15308269d98fa423254361cee" dependencies = [ "backtrace", "base64 0.13.0", @@ -4816,7 +4818,7 @@ dependencies = [ [[package]] name = "reaper-low" version = "0.1.0" -source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#21c06e5a5ab2478352303547926d38ccbefdf171" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#9db7c4c619630eb15308269d98fa423254361cee" dependencies = [ "c_str_macro", "cc 1.0.79", @@ -4830,7 +4832,7 @@ dependencies = [ [[package]] name = "reaper-macros" version = "0.1.0" -source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#21c06e5a5ab2478352303547926d38ccbefdf171" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#9db7c4c619630eb15308269d98fa423254361cee" dependencies = [ "darling 0.10.2", "quote 1.0.30", @@ -4840,7 +4842,7 @@ dependencies = [ [[package]] name = "reaper-medium" version = "0.1.0" -source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#21c06e5a5ab2478352303547926d38ccbefdf171" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#9db7c4c619630eb15308269d98fa423254361cee" dependencies = [ "c_str_macro", "derive_more", @@ -4858,7 +4860,7 @@ dependencies = [ [[package]] name = "reaper-rx" version = "0.1.0" -source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#21c06e5a5ab2478352303547926d38ccbefdf171" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#9db7c4c619630eb15308269d98fa423254361cee" dependencies = [ "crossbeam-channel", "helgoboss-midi", @@ -5064,7 +5066,7 @@ dependencies = [ [[package]] name = "rppxml-parser" version = "0.1.0" -source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#21c06e5a5ab2478352303547926d38ccbefdf171" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#9db7c4c619630eb15308269d98fa423254361cee" dependencies = [ "splitty", ] @@ -5915,6 +5917,20 @@ dependencies = [ "syn 2.0.23", ] +[[package]] +name = "thread-priority" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c56ce92f1285eaaa11fc1a3201e25de97898c50e87caa4c2aee836fe05288de" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "log", + "rustversion", + "winapi", +] + [[package]] name = "thread_local" version = "1.1.4" diff --git a/base/Cargo.toml b/base/Cargo.toml index e32ff60f1..c9009c789 100644 --- a/base/Cargo.toml +++ b/base/Cargo.toml @@ -28,4 +28,5 @@ ascii.workspace = true enigo = "0.0.14" device_query = "1.1.1" derive_more.workspace = true -slog.workspace = true \ No newline at end of file +slog.workspace = true +either.workspace = true \ No newline at end of file diff --git a/base/src/lib.rs b/base/src/lib.rs index 964501ac1..131f32897 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -39,3 +39,5 @@ mod trafficker; pub use trafficker::*; pub mod validation_util; + +pub mod peak_util; diff --git a/base/src/peak_util.rs b/base/src/peak_util.rs new file mode 100644 index 000000000..e06553a28 --- /dev/null +++ b/base/src/peak_util.rs @@ -0,0 +1,38 @@ +use either::Either; +use reaper_high::{Reaper, Track}; +use reaper_medium::{MediaTrack, ReaperVolumeValue, SoloMode, TrackAttributeKey}; +use std::iter; + +/// Returns whether the peaks should better be hidden even they are available. +/// +/// This is for the case if another track is soloed, reporting the peak would be misleading then. +pub fn peaks_should_be_hidden(track: &Track) -> bool { + let is_master = track.is_master_track(); + (is_master && track.is_muted()) + || (!is_master && track.project().any_solo() && track.solo_mode() == SoloMode::Off) +} + +/// Returns the track's peaks as iterator. +/// +/// This takes VU mode / channel count intricacies into account. It returns peaks even if another +/// track is soloed! See [`peaks_should_be_hidden`]. +pub fn get_track_peaks( + track: MediaTrack, +) -> impl Iterator + ExactSizeIterator { + let reaper = Reaper::get().medium_reaper(); + let vu_mode = + unsafe { reaper.get_media_track_info_value(track, TrackAttributeKey::VuMode) as i32 }; + let channel_count = if matches!(vu_mode, 2 | 8) { + // These VU modes have multi-channel support. + unsafe { reaper.get_media_track_info_value(track, TrackAttributeKey::Nchan) as i32 } + } else { + // Other VU modes always use stereo. + 2 + }; + if channel_count <= 0 { + return Either::Left(iter::empty()); + } + let iter = + (0..channel_count).map(move |ch| unsafe { reaper.track_get_peak_info(track, ch as u32) }); + Either::Right(iter) +} diff --git a/helgoboss-license-processor b/helgoboss-license-processor index dd0a7d573..894ed45c4 160000 --- a/helgoboss-license-processor +++ b/helgoboss-license-processor @@ -1 +1 @@ -Subproject commit dd0a7d573d0050e0bc45aec408ec257797b97427 +Subproject commit 894ed45c4aa479b6660181f2e8872b628e0dc99a diff --git a/main/src/domain/targets/track_peak_target.rs b/main/src/domain/targets/track_peak_target.rs index 6ba6c78bf..6fdc03923 100644 --- a/main/src/domain/targets/track_peak_target.rs +++ b/main/src/domain/targets/track_peak_target.rs @@ -6,6 +6,7 @@ use crate::domain::{ FeedbackResolution, RealearnTarget, ReaperTarget, ReaperTargetType, TargetCharacter, TargetTypeDef, TrackDescriptor, UnresolvedReaperTargetDef, DEFAULT_TARGET, }; +use base::peak_util; use helgoboss_learn::{AbsoluteValue, ControlType, NumericValue, Target, UnitValue}; use reaper_high::{Project, Reaper, Track, Volume}; use reaper_medium::{ReaperVolumeValue, SoloMode, TrackAttributeKey}; @@ -60,31 +61,15 @@ impl<'a> Target<'a> for TrackPeakTarget { impl TrackPeakTarget { fn peak(&self) -> Option { - let reaper = Reaper::get().medium_reaper(); - if self.track.project().any_solo() && self.track.solo_mode() == SoloMode::Off { - // Another track is soloed. In this case, reporting the peak would be misleading. + if peak_util::peaks_should_be_hidden(&self.track) { return Some(Volume::MIN); } - let vu_mode = unsafe { - reaper.get_media_track_info_value(self.track.raw(), TrackAttributeKey::VuMode) as i32 - }; - let channel_count = if matches!(vu_mode, 2 | 8) { - // These VU modes have multi-channel support. - unsafe { - reaper.get_media_track_info_value(self.track.raw(), TrackAttributeKey::Nchan) as i32 - } - } else { - // Other VU modes always use stereo. - 2 - }; - if channel_count <= 0 { + let peaks = peak_util::get_track_peaks(self.track.raw()); + let channel_count = peaks.len(); + if channel_count == 0 { return None; } - let mut sum = 0.0; - for ch in 0..channel_count { - let volume = unsafe { reaper.track_get_peak_info(self.track.raw(), ch as u32) }; - sum += volume.get(); - } + let sum: f64 = peaks.map(|v| v.get()).sum(); let avg = sum / channel_count as f64; let vol = ReaperVolumeValue::new(avg); Some(Volume::from_reaper_value(vol)) diff --git a/playtime-clip-engine b/playtime-clip-engine index 3125f7f28..d303ec631 160000 --- a/playtime-clip-engine +++ b/playtime-clip-engine @@ -1 +1 @@ -Subproject commit 3125f7f2873ded93d65428758c9f07770a711b18 +Subproject commit d303ec63125ed7bab791776f6f861d358063c4da