Skip to content

Commit

Permalink
Merge pull request #189 from GoXLR-on-Linux/vod-mode
Browse files Browse the repository at this point in the history
Vod mode
  • Loading branch information
FrostyCoolSlug authored Sep 8, 2024
2 parents c830040 + 9022daa commit 3f718e9
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 11 deletions.
63 changes: 54 additions & 9 deletions daemon/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use goxlr_types::{
Button, ChannelName, DeviceType, DisplayModeComponents, EffectBankPresets, EffectKey,
EncoderName, FaderName, HardTuneSource, InputDevice as BasicInputDevice, MicrophoneParamKey,
Mix, MuteState, OutputDevice as BasicOutputDevice, RobotRange, SampleBank, SampleButtons,
SamplePlaybackMode, VersionNumber, WaterfallDirection,
SamplePlaybackMode, VersionNumber, VodMode, WaterfallDirection,
};
use goxlr_usb::animation::{AnimationMode, WaterFallDir};
use goxlr_usb::buttonstate::{ButtonStates, Buttons};
Expand Down Expand Up @@ -277,6 +277,7 @@ impl<'a> Device<'a> {
.await;

let locked_faders = self.settings.get_device_lock_faders(self.serial()).await;
let vod_mode = self.settings.get_device_vod_mode(self.serial()).await;

let submix_supported = self.device_supports_submixes();

Expand Down Expand Up @@ -346,6 +347,7 @@ impl<'a> Device<'a> {
enable_monitor_with_fx: monitor_with_fx,
reset_sampler_on_clear: sampler_reset_on_clear,
lock_faders: locked_faders,
vod_mode,
},
button_down: button_states,
profile_name: self.profile.name().to_owned(),
Expand Down Expand Up @@ -2792,6 +2794,22 @@ impl<'a> Device<'a> {
self.load_colour_map().await?;
}
}

GoXLRCommand::SetVodMode(value) => {
let serial = self.serial();

// Get the current mode..
let current = self.settings.get_device_vod_mode(serial).await;
if current != value {
self.settings.set_device_vod_mode(serial, value).await;

// We need to reapply all routing to reconfigure as needed
for input in BasicInputDevice::iter() {
self.apply_routing(input).await?;
}
}
}

GoXLRCommand::SetActiveEffectPreset(preset) => {
self.load_effect_bank(preset).await?;
self.update_button_states()?;
Expand Down Expand Up @@ -2953,7 +2971,7 @@ impl<'a> Device<'a> {
Ok(())
}

fn apply_transient_routing(
async fn apply_transient_routing(
&self,
input: BasicInputDevice,
router: &mut EnumMap<BasicOutputDevice, bool>,
Expand All @@ -2972,21 +2990,22 @@ impl<'a> Device<'a> {

for fader in FaderName::iter() {
if self.profile.get_fader_assignment(fader) == channel_name {
self.apply_transient_fader_routing(channel_name, fader, router)?;
self.apply_transient_fader_routing(channel_name, fader, router)
.await?;
}
}

// Chat Mic has a Transient routing option related to the Voice Chat channel, we need
// to ensure that if we're handling the mic, we handle it here.
if channel_name == ChannelName::Mic {
self.apply_transient_chat_mic_mute(router)?;
self.apply_transient_cough_routing(router)?;
self.apply_transient_cough_routing(router).await?;
}

Ok(())
}

fn apply_transient_fader_routing(
async fn apply_transient_fader_routing(
&self,
channel_name: ChannelName,
fader: FaderName,
Expand All @@ -3000,9 +3019,10 @@ impl<'a> Device<'a> {
mute_function,
router,
)
.await
}

fn apply_transient_cough_routing(
async fn apply_transient_cough_routing(
&self,
router: &mut EnumMap<BasicOutputDevice, bool>,
) -> Result<()> {
Expand All @@ -3017,6 +3037,7 @@ impl<'a> Device<'a> {
mute_function,
router,
)
.await
}

fn apply_transient_chat_mic_mute(
Expand All @@ -3041,7 +3062,7 @@ impl<'a> Device<'a> {
Ok(())
}

fn apply_transient_channel_routing(
async fn apply_transient_channel_routing(
&self,
channel_name: ChannelName,
muted_to_x: bool,
Expand All @@ -3063,7 +3084,15 @@ impl<'a> Device<'a> {

match mute_function {
MuteFunction::All => {}
MuteFunction::ToStream => router[BasicOutputDevice::BroadcastMix] = false,
MuteFunction::ToStream => {
// Disable routing to the Stream Mix
router[BasicOutputDevice::BroadcastMix] = false;

// If we're a mini, with VOD Mode 'Stream No Music', disable this route to VOD.
if self.is_steam_no_music().await {
router[BasicOutputDevice::Sampler] = false;
}
}
MuteFunction::ToVoiceChat => router[BasicOutputDevice::ChatMic] = false,
MuteFunction::ToPhones => router[BasicOutputDevice::Headphones] = false,
MuteFunction::ToLineOut => router[BasicOutputDevice::LineOut] = false,
Expand All @@ -3090,7 +3119,18 @@ impl<'a> Device<'a> {
}
}

self.apply_transient_routing(input, &mut router)?;
if self.is_steam_no_music().await {
// Ok, so we need to sync the Mix channel to the Sample (VOD) Channel, unless Music
if input == BasicInputDevice::Music {
// Force Music -> Sample to Off
router[BasicOutputDevice::Sampler] = false;
} else {
// Sync the Mix and Sampler (VOD) channels
router[BasicOutputDevice::Sampler] = router[BasicOutputDevice::BroadcastMix];
}
}

self.apply_transient_routing(input, &mut router).await?;
debug!("Applying Routing to {:?}:", input);
debug!("{:?}", router);

Expand Down Expand Up @@ -3831,6 +3871,11 @@ impl<'a> Device<'a> {
DeviceType::Mini => version_newer_or_equal_to(current, support_mini),
}
}

async fn is_steam_no_music(&self) -> bool {
self.hardware.device_type == DeviceType::Mini
&& self.settings.get_device_vod_mode(self.serial()).await == VodMode::StreamNoMusic
}
}

fn tts_bool_to_state(bool: bool) -> String {
Expand Down
33 changes: 33 additions & 0 deletions daemon/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use crate::profile::DEFAULT_PROFILE_NAME;
use anyhow::{Context, Result};
use directories::ProjectDirs;
use goxlr_ipc::{GoXLRCommand, LogLevel};
use goxlr_types::VodMode;
use goxlr_types::VodMode::Routable;
use log::{debug, error, info, warn};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
Expand Down Expand Up @@ -447,6 +449,21 @@ impl SettingsHandle {
false
}

pub async fn get_device_vod_mode(&self, device_serial: &str) -> VodMode {
let settings = self.settings.read().await;
let value = settings
.devices
.as_ref()
.unwrap()
.get(device_serial)
.map(|d| d.vod_mode.unwrap_or(Routable));

if let Some(value) = value {
return value;
}
Routable
}

pub async fn get_sampler_reset_on_clear(&self, device_serial: &str) -> bool {
let settings = self.settings.read().await;
settings
Expand Down Expand Up @@ -597,6 +614,17 @@ impl SettingsHandle {
entry.enable_monitor_with_fx = Some(setting);
}

pub async fn set_device_vod_mode(&self, device_serial: &str, setting: VodMode) {
let mut settings = self.settings.write().await;
let entry = settings
.devices
.as_mut()
.unwrap()
.entry(device_serial.to_owned())
.or_insert_with(DeviceSettings::default);
entry.vod_mode = Some(setting);
}

pub async fn set_sampler_reset_on_clear(&self, device_serial: &str, setting: bool) {
let mut settings = self.settings.write().await;
let entry = settings
Expand Down Expand Up @@ -731,6 +759,9 @@ struct DeviceSettings {
// Clear Sample Settings when Clearing Button
sampler_reset_on_clear: Option<bool>,

// VoD 'Mode'
vod_mode: Option<VodMode>,

// 'Shutdown' commands..
shutdown_commands: Vec<GoXLRCommand>,
sleep_commands: Vec<GoXLRCommand>,
Expand All @@ -750,6 +781,8 @@ impl Default for DeviceSettings {
enable_monitor_with_fx: Some(false),
sampler_reset_on_clear: Some(true),

vod_mode: Some(Routable),

shutdown_commands: vec![],
sleep_commands: vec![],
wake_commands: vec![],
Expand Down
3 changes: 2 additions & 1 deletion ipc/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use goxlr_types::{
MegaphoneStyle, MicrophoneType, MiniEqFrequencies, Mix, MuteFunction, MuteState, OutputDevice,
PitchStyle, ReverbStyle, RobotStyle, SampleBank, SampleButtons, SamplePlayOrder,
SamplePlaybackMode, SamplerColourTargets, SimpleColourTargets, SubMixChannelName,
VersionNumber, WaterfallDirection,
VersionNumber, VodMode, WaterfallDirection,
};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
Expand Down Expand Up @@ -396,6 +396,7 @@ pub struct Settings {
pub enable_monitor_with_fx: bool,
pub reset_sampler_on_clear: bool,
pub lock_faders: bool,
pub vod_mode: VodMode,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
3 changes: 2 additions & 1 deletion ipc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use goxlr_types::{
FaderDisplayStyle, FaderName, GateTimes, GenderStyle, HardTuneSource, HardTuneStyle,
InputDevice, MegaphoneStyle, MicrophoneType, MiniEqFrequencies, Mix, MuteFunction, MuteState,
OutputDevice, PitchStyle, ReverbStyle, RobotRange, RobotStyle, SampleBank, SampleButtons,
SamplePlayOrder, SamplePlaybackMode, SamplerColourTargets, SimpleColourTargets,
SamplePlayOrder, SamplePlaybackMode, SamplerColourTargets, SimpleColourTargets, VodMode,
WaterfallDirection,
};

Expand Down Expand Up @@ -268,6 +268,7 @@ pub enum GoXLRCommand {
SetMonitorWithFx(bool),
SetSamplerResetOnClear(bool),
SetLockFaders(bool),
SetVodMode(VodMode),

// These control the current GoXLR 'State'..
SetActiveEffectPreset(EffectBankPresets),
Expand Down
9 changes: 9 additions & 0 deletions types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,15 @@ pub enum WaterfallDirection {
Off,
}

#[derive(Default, Debug, Copy, Clone, EnumIter, Display, PartialEq, Eq)]
#[cfg_attr(feature = "clap", derive(ValueEnum))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum VodMode {
#[default]
Routable,
StreamNoMusic,
}

#[derive(Default, Debug, Clone, Enum, PartialEq, Eq)]
#[cfg_attr(feature = "clap", derive(ValueEnum))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand Down

0 comments on commit 3f718e9

Please sign in to comment.