Skip to content

Commit

Permalink
Playtime: Add learning for some toolbar actions
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Mar 11, 2024
1 parent b3bc633 commit 1b3f7d1
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 66 deletions.
12 changes: 12 additions & 0 deletions api/src/persistence/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1515,6 +1515,18 @@ pub enum PlaytimeMatrixAction {
ClickOnOffState,
#[display(fmt = "Enable/disable MIDI auto-quantize")]
MidiAutoQuantizationOnOffState,
#[display(fmt = "Smart record")]
SmartRecord,
#[display(fmt = "Enable silence mode or play ignited")]
EnterSilenceModeOrPlayIgnited,
#[display(fmt = "Enable/disable silence mode")]
SilenceModeOnOffState,
#[display(fmt = "Panic")]
Panic,
#[display(fmt = "Enable/disable sequencer recording")]
SequencerRecordOnOffState,
#[display(fmt = "Enable/disable sequencer playing")]
SequencerPlayOnOffState,
}

impl Default for PlaytimeMatrixAction {
Expand Down
43 changes: 31 additions & 12 deletions main/src/application/target_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,14 @@ use std::error::Error;

use crate::domain::ui_util::format_tags_as_csv;
use base::hash_util::NonCryptoHashSet;
use realearn_api::persistence::Target::PlaytimeColumnAction;
use realearn_api::persistence::{
Axis, BrowseTracksMode, FxChainDescriptor, FxDescriptorCommons, FxToolAction,
LearnTargetMappingModification, LearnableTargetKind, MappingModification,
MappingSnapshotDescForLoad, MappingSnapshotDescForTake, MonitoringMode, MouseAction,
MouseButton, PlaytimeColumnDescriptor, PlaytimeRowDescriptor, PlaytimeSlotDescriptor,
PotFilterKind, SeekBehavior, SetTargetToLastTouchedMappingModification, TargetTouchCause,
TrackDescriptorCommons, TrackFxChain, TrackScope, TrackToolAction,
MouseButton, PlaytimeColumnDescriptor, PlaytimeMatrixAction, PlaytimeRowDescriptor,
PlaytimeSlotDescriptor, PotFilterKind, SeekBehavior, SetTargetToLastTouchedMappingModification,
TargetTouchCause, TrackDescriptorCommons, TrackFxChain, TrackScope, TrackToolAction,
};
use reaper_medium::{
AutomationMode, BookmarkId, GlobalAutomationModeOverride, InputMonitoringMode, TrackArea,
Expand Down Expand Up @@ -1780,6 +1781,15 @@ impl TargetModel {
self.automation_mode = RealearnAutomationMode::from_reaper(am);
}
},
PlaytimeMatrixAction(t) => {
self.clip_matrix_action = t.action;
}
PlaytimeColumnAction(t) => {
self.clip_column_action = t.action;
}
PlaytimeRowAction(t) => {
self.clip_row_action = t.basics.action;
}
PlaytimeSlotTransportAction(t) => {
self.clip_transport_action = t.basics.action;
}
Expand Down Expand Up @@ -2667,32 +2677,41 @@ impl TargetModel {
pub fn simple_target(&self) -> Option<playtime_api::runtime::SimpleMappingTarget> {
use playtime_api::runtime::SimpleMappingTarget;
use realearn_api::persistence;
use ReaperTargetType::*;
use ReaperTargetType as T;
if self.category != TargetCategory::Reaper {
return None;
}
let t = match self.r#type {
PlaytimeSlotTransportAction
T::PlaytimeSlotTransportAction
if self.clip_transport_action()
== persistence::PlaytimeSlotTransportAction::Trigger =>
{
SimpleMappingTarget::TriggerSlot(self.clip_slot.fixed_address()?)
}
PlaytimeColumnAction
T::PlaytimeColumnAction
if self.clip_column_action() == persistence::PlaytimeColumnAction::Stop =>
{
SimpleMappingTarget::TriggerColumn(self.clip_column.fixed_address()?)
}
PlaytimeRowAction
T::PlaytimeRowAction
if self.clip_row_action() == persistence::PlaytimeRowAction::PlayScene =>
{
SimpleMappingTarget::TriggerRow(self.clip_row.fixed_address()?)
}
PlaytimeMatrixAction
if self.clip_matrix_action() == persistence::PlaytimeMatrixAction::Stop =>
{
SimpleMappingTarget::TriggerMatrix
}
T::PlaytimeMatrixAction => match self.clip_matrix_action {
PlaytimeMatrixAction::Stop => SimpleMappingTarget::TriggerMatrix,
PlaytimeMatrixAction::SmartRecord => SimpleMappingTarget::SmartRecord,
PlaytimeMatrixAction::EnterSilenceModeOrPlayIgnited => {
SimpleMappingTarget::EnterSilenceModeOrPlayIgnited
}
PlaytimeMatrixAction::SequencerRecordOnOffState => {
SimpleMappingTarget::SequencerRecordOnOffState
}
PlaytimeMatrixAction::SequencerPlayOnOffState => {
SimpleMappingTarget::SequencerPlayOnOffState
}
_ => return None,
},
_ => return None,
};
Some(t)
Expand Down
82 changes: 48 additions & 34 deletions main/src/domain/reaper_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ use strum::EnumIter;
use helgoboss_learn::{
AbsoluteValue, ControlType, ControlValue, NumericValue, PropValue, Target, UnitValue,
};
use realearn_api::persistence::{SeekBehavior, TrackScope};
use realearn_api::persistence::{
PlaytimeColumnAction, PlaytimeMatrixAction, PlaytimeRowAction, PlaytimeSlotTransportAction,
SeekBehavior, TrackScope,
};

use crate::domain::ui_util::convert_bool_to_unit_value;
use crate::domain::{
Expand All @@ -32,12 +35,14 @@ use crate::domain::{
FxOnlineTarget, FxOpenTarget, FxParameterTarget, FxParameterTouchStateTarget, FxPresetTarget,
FxToolTarget, GoToBookmarkTarget, HierarchyEntry, HierarchyEntryProvider, LoadFxSnapshotTarget,
LoadPotPresetTarget, MappingControlContext, MidiSendTarget, ModifyMappingTarget, OscSendTarget,
PlayrateTarget, PreviewPotPresetTarget, RealTimeControlContext, RealTimeFxParameterTarget,
RouteMuteTarget, RoutePanTarget, RouteTouchStateTarget, RouteVolumeTarget, SeekTarget,
TakeMappingSnapshotTarget, TargetTypeDef, TempoTarget, TrackArmTarget,
TrackAutomationModeTarget, TrackMonitoringModeTarget, TrackMuteTarget, TrackPanTarget,
TrackParentSendTarget, TrackPeakTarget, TrackSelectionTarget, TrackShowTarget, TrackSoloTarget,
TrackTouchStateTarget, TrackVolumeTarget, TrackWidthTarget, TransportTarget, UnitEvent,
PlayrateTarget, PlaytimeColumnActionTarget, PlaytimeMatrixActionTarget,
PlaytimeRowActionTarget, PlaytimeSlotTransportTarget, PreviewPotPresetTarget,
RealTimeControlContext, RealTimeFxParameterTarget, RouteMuteTarget, RoutePanTarget,
RouteTouchStateTarget, RouteVolumeTarget, SeekTarget, TakeMappingSnapshotTarget, TargetTypeDef,
TempoTarget, TrackArmTarget, TrackAutomationModeTarget, TrackMonitoringModeTarget,
TrackMuteTarget, TrackPanTarget, TrackParentSendTarget, TrackPeakTarget, TrackSelectionTarget,
TrackShowTarget, TrackSoloTarget, TrackTouchStateTarget, TrackVolumeTarget, TrackWidthTarget,
TransportTarget, UnitEvent,
};
use crate::domain::{
AnyOnTarget, BrowseGroupMappingsTarget, CompoundChangeEvent, EnableInstancesTarget,
Expand All @@ -47,6 +52,7 @@ use crate::domain::{
};
use base::default_util::is_default;
use base::Global;
use playtime_api::runtime::SimpleMappingTarget;

/// This target character is just used for GUI and auto-correct settings! It doesn't have influence
/// on control/feedback.
Expand Down Expand Up @@ -138,11 +144,11 @@ pub enum ReaperTarget {
SendMidi(MidiSendTarget),
SendOsc(OscSendTarget),
Dummy(DummyTarget),
PlaytimeMatrixAction(crate::domain::PlaytimeMatrixActionTarget),
PlaytimeMatrixAction(PlaytimeMatrixActionTarget),
PlaytimeControlUnitScroll(crate::domain::PlaytimeControlUnitScrollTarget),
PlaytimeSlotTransportAction(crate::domain::PlaytimeSlotTransportTarget),
PlaytimeColumnAction(crate::domain::PlaytimeColumnActionTarget),
PlaytimeRowAction(crate::domain::PlaytimeRowActionTarget),
PlaytimeSlotTransportAction(PlaytimeSlotTransportTarget),
PlaytimeColumnAction(PlaytimeColumnActionTarget),
PlaytimeRowAction(PlaytimeRowActionTarget),
PlaytimeSlotSeek(crate::domain::PlaytimeSlotSeekTarget),
PlaytimeSlotVolume(crate::domain::PlaytimeSlotVolumeTarget),
PlaytimeSlotManagementAction(crate::domain::PlaytimeSlotManagementActionTarget),
Expand Down Expand Up @@ -273,36 +279,44 @@ impl Default for FxDisplayType {
}

impl ReaperTarget {
pub fn from_simple_target(simple_target: playtime_api::runtime::SimpleMappingTarget) -> Self {
use playtime_api::runtime::SimpleMappingTarget::*;
pub fn from_simple_target(simple_target: SimpleMappingTarget) -> Self {
use SimpleMappingTarget::*;
match simple_target {
TriggerMatrix => {
Self::PlaytimeMatrixAction(crate::domain::PlaytimeMatrixActionTarget {
action: realearn_api::persistence::PlaytimeMatrixAction::Stop,
})
}
TriggerColumn(t) => {
Self::PlaytimeColumnAction(crate::domain::PlaytimeColumnActionTarget {
column_index: t.index,
action: realearn_api::persistence::PlaytimeColumnAction::Stop,
})
}
TriggerRow(t) => Self::PlaytimeRowAction(crate::domain::PlaytimeRowActionTarget {
TriggerMatrix => Self::PlaytimeMatrixAction(PlaytimeMatrixActionTarget {
action: PlaytimeMatrixAction::Stop,
}),
TriggerColumn(t) => Self::PlaytimeColumnAction(PlaytimeColumnActionTarget {
column_index: t.index,
action: PlaytimeColumnAction::Stop,
}),
TriggerRow(t) => Self::PlaytimeRowAction(PlaytimeRowActionTarget {
basics: crate::domain::ClipRowTargetBasics {
row_index: t.index,
action: realearn_api::persistence::PlaytimeRowAction::PlayScene,
action: PlaytimeRowAction::PlayScene,
},
}),
TriggerSlot(t) => {
Self::PlaytimeSlotTransportAction(crate::domain::PlaytimeSlotTransportTarget {
project: Reaper::get().current_project(),
basics: crate::domain::ClipTransportTargetBasics {
slot_address: t,
action: realearn_api::persistence::PlaytimeSlotTransportAction::Trigger,
options: Default::default(),
},
TriggerSlot(t) => Self::PlaytimeSlotTransportAction(PlaytimeSlotTransportTarget {
project: Reaper::get().current_project(),
basics: crate::domain::ClipTransportTargetBasics {
slot_address: t,
action: PlaytimeSlotTransportAction::Trigger,
options: Default::default(),
},
}),
SmartRecord => Self::PlaytimeMatrixAction(PlaytimeMatrixActionTarget {
action: PlaytimeMatrixAction::SmartRecord,
}),
EnterSilenceModeOrPlayIgnited => {
Self::PlaytimeMatrixAction(PlaytimeMatrixActionTarget {
action: PlaytimeMatrixAction::EnterSilenceModeOrPlayIgnited,
})
}
SequencerRecordOnOffState => Self::PlaytimeMatrixAction(PlaytimeMatrixActionTarget {
action: PlaytimeMatrixAction::SequencerRecordOnOffState,
}),
SequencerPlayOnOffState => Self::PlaytimeMatrixAction(PlaytimeMatrixActionTarget {
action: PlaytimeMatrixAction::SequencerPlayOnOffState,
}),
}
}

Expand Down
73 changes: 70 additions & 3 deletions main/src/domain/targets/playtime_matrix_action_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,14 @@ mod playtime_impl {
use helgoboss_learn::{AbsoluteValue, ControlType, ControlValue, Target, UnitValue};

use playtime_api::persistence::{EvenQuantization, RecordLength};
use playtime_clip_engine::base::{ClipMatrixEvent, Matrix};
use playtime_clip_engine::base::{ClipMatrixEvent, Matrix, SequencerStatus};
use playtime_clip_engine::rt::{QualifiedSlotChangeEvent, SlotChangeEvent};
use realearn_api::persistence::PlaytimeMatrixAction;

use realearn_api::persistence::PlaytimeMatrixAction::{
EnterSilenceModeOrPlayIgnited, SequencerPlayOnOffState, SequencerRecordOnOffState,
SilenceModeOnOffState,
};
use std::borrow::Cow;

impl PlaytimeMatrixActionTarget {
Expand Down Expand Up @@ -148,6 +152,46 @@ mod playtime_impl {
PlaytimeMatrixAction::MidiAutoQuantizationOnOffState => {
matrix.set_midi_auto_quantize_enabled(value.is_on());
}
PlaytimeMatrixAction::SmartRecord => {
if !value.is_on() {
return Ok(HitResponse::ignored());
}
matrix.trigger_smart_record()?;
}
PlaytimeMatrixAction::EnterSilenceModeOrPlayIgnited => {
if value.is_on() {
matrix.enter_silence_mode();
} else {
matrix.play_all_ignited();
}
}
PlaytimeMatrixAction::SilenceModeOnOffState => {
if value.is_on() {
matrix.enter_silence_mode();
} else {
matrix.leave_silence_mode();
}
}
PlaytimeMatrixAction::Panic => {
if !value.is_on() {
return Ok(HitResponse::ignored());
}
matrix.panic();
}
PlaytimeMatrixAction::SequencerRecordOnOffState => {
if value.is_on() {
matrix.record_new_sequence();
} else {
matrix.stop_sequencer();
}
}
PlaytimeMatrixAction::SequencerPlayOnOffState => {
if value.is_on() {
matrix.play_active_sequence()?;
} else {
matrix.stop_sequencer();
}
}
}
Ok(HitResponse::processed_with_effect())
}
Expand Down Expand Up @@ -281,6 +325,22 @@ mod playtime_impl {
PlaytimeMatrixAction::MidiAutoQuantizationOnOffState => {
matrix.midi_auto_quantize_enabled()
}
PlaytimeMatrixAction::SmartRecord => {
return None;
}
PlaytimeMatrixAction::EnterSilenceModeOrPlayIgnited => {
matrix.is_in_silence_mode()
}
PlaytimeMatrixAction::SilenceModeOnOffState => matrix.is_in_silence_mode(),
PlaytimeMatrixAction::Panic => {
return None;
}
PlaytimeMatrixAction::SequencerRecordOnOffState => {
matrix.sequencer().status() == SequencerStatus::Recording
}
PlaytimeMatrixAction::SequencerPlayOnOffState => {
matrix.sequencer().status() == SequencerStatus::Playing
}
};
Some(AbsoluteValue::from_bool(bool_value))
})
Expand Down Expand Up @@ -341,11 +401,18 @@ mod playtime_impl {
| Stop
| Undo
| Redo
| BuildScene => (
| BuildScene
| Panic
| SmartRecord => (
ControlType::AbsoluteContinuousRetriggerable,
TargetCharacter::Trigger,
),
ClickOnOffState | MidiAutoQuantizationOnOffState => {
ClickOnOffState
| MidiAutoQuantizationOnOffState
| SilenceModeOnOffState
| SequencerRecordOnOffState
| SequencerPlayOnOffState
| EnterSilenceModeOrPlayIgnited => {
(ControlType::AbsoluteContinuous, TargetCharacter::Switch)
}
}
Expand Down
Loading

0 comments on commit 1b3f7d1

Please sign in to comment.