From bff9cf826fc493c3d580f5bca1746c1bbaf3e5a7 Mon Sep 17 00:00:00 2001 From: Nuwan Date: Fri, 28 Nov 2025 11:44:16 +0530 Subject: [PATCH] updating the backend when volume changes --- .../components/client/JKSessionVolumeModal.js | 25 ++- .../src/components/client/SessionTrackGain.js | 56 +++---- jam-ui/src/hooks/useMixerHelper.js | 158 ++++++++---------- 3 files changed, 115 insertions(+), 124 deletions(-) diff --git a/jam-ui/src/components/client/JKSessionVolumeModal.js b/jam-ui/src/components/client/JKSessionVolumeModal.js index 17837dcb5..2f3e9ed43 100644 --- a/jam-ui/src/components/client/JKSessionVolumeModal.js +++ b/jam-ui/src/components/client/JKSessionVolumeModal.js @@ -7,23 +7,36 @@ import { import SessionTrackVU from './SessionTrackVU'; import SessionTrackGain from './SessionTrackGain' import { useMixersContext } from '../../context/MixersContext'; +import { ChannelGroupIds } from '../../helpers/globals.js'; const JKSessionVolumeModal = ({ isOpen, toggle }) => { const mixerHelper = useMixersContext(); const mixers = mixerHelper.myTracks[0]?.mixers; - // Get the simulated mixers for the current mode + // Get the real backend mixers for volume controls (like web version) const getMusicMixers = () => { - if (mixerHelper?.simulatedMusicCategoryMixers && mixerHelper?.mixMode !== undefined) { - return mixerHelper.simulatedMusicCategoryMixers[mixerHelper.mixMode]; + const allMixers = mixerHelper.mixers; + const mode = mixerHelper.mixMode; + const targetGroupId = mode === true ? ChannelGroupIds.MasterGroup : ChannelGroupIds.MonitorGroup; + + // Find the real mixer with correct volume values + for (const key in allMixers) { + if (allMixers[key] && allMixers[key].group_id === targetGroupId) { + return allMixers[key]; // Return the real mixer object + } } return null; }; const getChatMixers = () => { - if (mixerHelper?.simulatedChatCategoryMixers && mixerHelper?.mixMode !== undefined) { - // Now simulatedChatCategoryMixers[mixMode] returns the mixer object directly - return mixerHelper.simulatedChatCategoryMixers[mixerHelper.mixMode]; + const allMixers = mixerHelper.mixers; + const targetGroupId = ChannelGroupIds.AudioInputChatGroup; + + // Find the real chat mixer with correct volume values + for (const key in allMixers) { + if (allMixers[key] && allMixers[key].group_id === targetGroupId) { + return allMixers[key]; // Return the real mixer object + } } return null; }; diff --git a/jam-ui/src/components/client/SessionTrackGain.js b/jam-ui/src/components/client/SessionTrackGain.js index 775fd4a69..107b7d843 100644 --- a/jam-ui/src/components/client/SessionTrackGain.js +++ b/jam-ui/src/components/client/SessionTrackGain.js @@ -21,11 +21,8 @@ const SessionTrackGain = ({ // Get the mixer to work with const getMixer = useCallback(() => { - let mixer = mixers?.mixer; - if (mixer && Array.isArray(mixer)) { - mixer = mixer[0]; - } - return mixer; + // Now mixers is a real mixer object directly, not a nested structure + return mixers; }, [mixers]); // Initialize value from mixer @@ -38,12 +35,28 @@ const SessionTrackGain = ({ }, [getMixer, faderHelpers]); const [currentValue, setCurrentValue] = useState(getInitialValue); + const prevVolumeRef = useRef(); - // Update value when mixer changes + // Update value when mixer changes or volume changes useEffect(() => { - const newValue = getInitialValue(); - setCurrentValue(newValue); - }, [getInitialValue]); + const mixer = mixers; + const currentVolume = mixer?.volume_left; + + // Check if volume has actually changed + if (currentVolume !== prevVolumeRef.current) { + prevVolumeRef.current = currentVolume; + + if (mixer && currentVolume !== undefined) { + const newValue = faderHelpers.convertAudioTaperToPercent(currentVolume); + console.log("SessionTrackGain: initial value", newValue); + setCurrentValue(newValue); + mixerHelper.initGain(mixer); + } else { + setCurrentValue(50); // fallback + } + } + }, [mixers, faderHelpers, mixerHelper]); + // Function to calculate and update the slider's position and value const updateSlider = useCallback(async (clientPos) => { @@ -68,31 +81,18 @@ const SessionTrackGain = ({ // Calculate the percentage const percentage = clampedPosition / trackSize * 100; - // Update the mixer - handle special cases like web version + // Update the mixer - now mixers is a real mixer object directly if (mixers) { - let mixersToUpdate = mixers.mixer || mixers; - - // Handle special cases for media tracks, jam tracks, etc. - // Similar to web version logic - if (mixers.mixer && !Array.isArray(mixers.mixer)) { - const mixer = mixers.mixer; - // Check if this is a media track, jam track, or media category - if (mixer.group_id === 3 || mixer.group_id === 4 || // MediaTrackGroup, JamTrackGroup - ((mixer.group_id === 6 || mixer.group_id === 7) && mixer.name === 'MediaTrack')) { // MonitorCatGroup, MasterCatGroup with MediaTrack - if (mixers.oppositeMixer) { - mixersToUpdate = [mixer, mixers.oppositeMixer]; - } - } - } - await mixerHelper.faderChanged( { percentage, dragging: isDragging }, - mixersToUpdate, + mixers, // Pass the real mixer object directly gainType, controlGroup ); } + console.log("SessionTrackGain: updateSlider", { clientPos, clampedPosition, percentage }); + // Update local state for UI setCurrentValue(Math.round(percentage)); @@ -117,7 +117,7 @@ const SessionTrackGain = ({ window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mouseup', handleMouseUp); if (sliderThumbRef.current) { - sliderThumbRef.current.classList.remove('dragging'); + sliderThumbRef.current.classList.remove('dragging'); } }, [handleMouseMove]); @@ -129,7 +129,7 @@ const SessionTrackGain = ({ window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mouseup', handleMouseUp); if (sliderThumbRef.current) { - sliderThumbRef.current.classList.add('dragging'); + sliderThumbRef.current.classList.add('dragging'); } }; diff --git a/jam-ui/src/hooks/useMixerHelper.js b/jam-ui/src/hooks/useMixerHelper.js index 95bccb175..ea46ed64d 100644 --- a/jam-ui/src/hooks/useMixerHelper.js +++ b/jam-ui/src/hooks/useMixerHelper.js @@ -106,76 +106,41 @@ const useMixerHelper = () => { const setMixerVolume = useCallback(async (mixer, volumePercent, relative, originalVolume, controlGroup) => { const newVolume = faderHelpers.convertPercentToAudioTaper(volumePercent); + + let updatedTrackVolumeObject; if (relative) { - - setTrackVolumeObject((prev) => ({ - ...prev, - volL: prev.volL + (newVolume - originalVolume), - })); + updatedTrackVolumeObject = { + ...trackVolumeObject, + volL: trackVolumeObject.volL + (newVolume - originalVolume), + volR: trackVolumeObject.volR + (newVolume - originalVolume), + }; - setTrackVolumeObject((prev) => ({ - ...prev, - volR: prev.volR + (newVolume - originalVolume), - })); - - // if (context.trackVolumeObject.volL < -80) { - // context.trackVolumeObject.volL = -80; - // } else if (context.trackVolumeObject.volL > 20) { - // context.trackVolumeObject.volL = 20; - // } - if(trackVolumeObject.volL < -80) { - setTrackVolumeObject((prev) => ({ - ...prev, - volL: -80, - })); - } else if (trackVolumeObject.volL > 20) { - setTrackVolumeObject((prev) => ({ - ...prev, - volL: 20, - })); - } - - - // if (context.trackVolumeObject.volR < -80) { - // context.trackVolumeObject.volR = -80; - // } else if (context.trackVolumeObject.volR > 20) { - // context.trackVolumeObject.volR = 20; - // } - if(trackVolumeObject.volR < -80) { - setTrackVolumeObject((prev) => ({ - ...prev, - volR: -80, - })); - } else if (trackVolumeObject.volR > 20) { - setTrackVolumeObject((prev) => ({ - ...prev, - volR: 20, - })); - } - + // Apply clamping + if (updatedTrackVolumeObject.volL < -80) updatedTrackVolumeObject.volL = -80; + if (updatedTrackVolumeObject.volL > 20) updatedTrackVolumeObject.volL = 20; + if (updatedTrackVolumeObject.volR < -80) updatedTrackVolumeObject.volR = -80; + if (updatedTrackVolumeObject.volR > 20) updatedTrackVolumeObject.volR = 20; } else { - // context.trackVolumeObject.volL = newVolume; - // context.trackVolumeObject.volR = newVolume; - setTrackVolumeObject((prev) => ({ - ...prev, + updatedTrackVolumeObject = { + ...trackVolumeObject, volL: newVolume, volR: newVolume, - })); - + }; } + // Update state + setTrackVolumeObject(updatedTrackVolumeObject); + + // Use the computed object for jamClient call if (controlGroup != null) { - let controlGroupsArg; - if (mixer.mode === MIX_MODES.PERSONAL) { - controlGroupsArg = 0; - } else { - controlGroupsArg = 1; - } - await jamClient.setSessionMixerCategoryPlayoutState(controlGroup === 'music', controlGroupsArg, trackVolumeObject.volL); + const controlGroupsArg = mixer.mode === MIX_MODES.PERSONAL ? 0 : 1; + console.log("setMixerVolume: setting session mixer category playout state for controlGroup", controlGroup, "controlGroupsArg", controlGroupsArg, "volume", updatedTrackVolumeObject.volL); + await jamClient.setSessionMixerCategoryPlayoutState(controlGroup === 'music', controlGroupsArg, updatedTrackVolumeObject.volL); } else { - await jamClient.SessionSetTrackVolumeData(mixer.id, mixer.mode, trackVolumeObject); + console.log("setMixerVolume: setting session mixer volume for mixer", mixer.id, "mode", mixer.mode, "volume", updatedTrackVolumeObject.volL); + await jamClient.SessionSetTrackVolumeData(mixer.id, mixer.mode, updatedTrackVolumeObject); } - }, []); + }, [trackVolumeObject, faderHelpers, jamClient]); const mediaMixers = useCallback((masterMixer, isOpener, currentAllMixers) => { const personalMixer = isOpener ? getMixerByResourceId(masterMixer.rid, MIX_MODES.PERSONAL, currentAllMixers) : masterMixer; @@ -1095,38 +1060,49 @@ const useMixerHelper = () => { }, []); const faderChanged = useCallback(async (data, mixers, gainType, controlGroup) => { + //console.log("MixerHelper: faderChanged called", { data, mixers, gainType, controlGroup }); if (!Array.isArray(mixers)) { mixers = [mixers]; } const originalVolume = getOriginalVolume(mixers, gainType); - if (controlGroup != null) { - mixers = [mixers[0]]; - for (const m of mixers) { - const broadcast = !(data.dragging); - const mixer = fillTrackVolumeObject(m.id, m.mode, allMixers, broadcast); - if (mixer == null) { - console.error("MixerHelper: faderChanged: mixer is null, skipping", m, gainType, controlGroup); - continue; - } - const relative = gainType === 'music' && (mixer.name === CategoryGroupIds.UserMedia || mixer.name === CategoryGroupIds.MediaTrack); - await setMixerVolume(mixer, data.percentage, relative, originalVolume, controlGroup, allMixers); - const updatedMixer = getMixer(mixer.id, mixer.mode, allMixers); - updatedMixer.volume_left = trackVolumeObject.volL; - } - } else { - for (const m of mixers) { - const broadcast = !(data.dragging); - const mixer = fillTrackVolumeObject(m.id, m.mode, allMixers, broadcast); - if (mixer == null) { - console.error("MixerHelper: faderChanged: mixer is null, skipping", m, gainType, controlGroup); - continue; - } - const relative = gainType === 'music' && (mixer.name === CategoryGroupIds.UserMedia || mixer.name === CategoryGroupIds.MediaTrack); - await setMixerVolume(mixer, data.percentage, relative, originalVolume, null, allMixers); - const updatedMixer = getMixer(mixer.id, mixer.mode, allMixers); - updatedMixer.volume_left = context.trackVolumeObject.volL; + console.log("MixerHelper: faderChanged called", { data, mixers, gainType, controlGroup, originalVolume }); + + // Handle multiple mixers (master + personal pairs like web version) + const mixerIds = mixers.map(m => m.id); + const hasMasterAndPersonalControls = mixerIds.length === 2; + + for (let i = 0; i < mixers.length; i++) { + const m = mixers[i]; + + // Broadcast only when NOT dragging (matches web version logic) + const broadcast = !(data.dragging); + + // Determine mode for multiple mixers (like web version) + let mode = m.mode; + if (hasMasterAndPersonalControls) { + mode = i === 0 ? MIX_MODES.MASTER : MIX_MODES.PERSONAL; } + + const mixer = fillTrackVolumeObject(m.id, mode, allMixers, broadcast); + if (mixer == null) { + console.error("MixerHelper: faderChanged: mixer is null, skipping", m, gainType, controlGroup); + continue; + } + + // Handle relative volume adjustments for music category (matches web version) + const relative = gainType === 'music' && (mixer.name === CategoryGroupIds.UserMedia || mixer.name === CategoryGroupIds.MediaTrack); + + await setMixerVolume(mixer, data.percentage, relative, originalVolume, controlGroup, allMixers); + + // Update local mixer state - create new state object to trigger React re-renders + setAllMixers(prev => ({ + ...prev, + [`${mixer.mode ? 'M' : 'P'}${mixer.id}`]: { + ...prev[`${mixer.mode ? 'M' : 'P'}${mixer.id}`], + volume_left: trackVolumeObject.volL + } + })); } }, [getOriginalVolume, getMixer, fillTrackVolumeObject, setMixerVolume, allMixers]); @@ -1135,9 +1111,10 @@ const useMixerHelper = () => { mixer = mixer[0]; } - const gainPercent = faderHelpers.convertAudioTaperToPercent(mixer.volume_left); - faderHelpers.setFaderValue(mixer.id, gainPercent); - faderHelpers.showFader(mixer.id); + // In React version, fader initialization is handled through component state + // This function is kept for API compatibility with web version + // No DOM manipulation needed since React handles state updates + console.debug('initGain called for mixer:', mixer?.id); }, []); const panChanged = useCallback(async (data, mixers, groupId) => { @@ -1379,7 +1356,8 @@ const useMixerHelper = () => { simulatedMusicCategoryMixers, simulatedChatCategoryMixers, mixMode, - faderChanged + faderChanged, + initGain }; }