Update audioreactive

This commit is contained in:
kijai 2023-12-12 16:03:37 +02:00
parent d03d74fb15
commit c4c5e172d5
2 changed files with 35 additions and 56 deletions

View File

@ -2667,42 +2667,31 @@ class SoundReactive:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": { return {"required": {
"average_level": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 99999, "step": 0.01}), "sound_level": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 99999, "step": 0.01}),
"low_level": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 99999, "step": 0.01}), "start_range_hz": ("INT", {"default": 150, "min": 0, "max": 9999, "step": 1}),
"mid_level": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 99999, "step": 0.01}), "end_range_hz": ("INT", {"default": 2000, "min": 0, "max": 9999, "step": 1}),
"high_level": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 99999, "step": 0.01}),
"low_range_hz": ("INT", {"default": 150, "min": 0, "max": 9999, "step": 1}),
"mid_range_hz": ("INT", {"default": 2000, "min": 0, "max": 9999, "step": 1}),
"multiplier": ("FLOAT", {"default": 1.0, "min": 0.01, "max": 99999, "step": 0.01}), "multiplier": ("FLOAT", {"default": 1.0, "min": 0.01, "max": 99999, "step": 0.01}),
"smoothing_factor": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
"normalize": ("BOOLEAN", {"default": False}), "normalize": ("BOOLEAN", {"default": False}),
}, },
} }
RETURN_TYPES = ("FLOAT","FLOAT","FLOAT","FLOAT","INT","INT","INT","INT") RETURN_TYPES = ("FLOAT","INT",)
RETURN_NAMES =("average_level", "low_level", "mid_level", "high_level", "average_level_int", "low_level_int", "mid_level_int", "high_level_int") RETURN_NAMES =("sound_level", "sound_level_int",)
FUNCTION = "react" FUNCTION = "react"
CATEGORY = "KJNodes/experimental" CATEGORY = "KJNodes/experimental"
def react(self, low_level, mid_level, high_level, low_range_hz, mid_range_hz, average_level, multiplier, normalize): def react(self, sound_level, start_range_hz, end_range_hz, smoothing_factor, multiplier, normalize):
low_level *= multiplier
mid_level *= multiplier sound_level *= multiplier
high_level *= multiplier
average_level = average_level * multiplier
if normalize: if normalize:
low_level = low_level / 255 sound_level /= 255
mid_level = mid_level / 255
high_level = high_level / 255
average_level = average_level / 255
low_level_int = int(low_level) sound_level_int = int(sound_level)
mid_level_int = int(mid_level)
high_level_int = int(high_level)
average_level_int = int(average_level)
return (sound_level, sound_level_int, )
return (average_level, low_level, mid_level, high_level, average_level_int, low_level_int, mid_level_int, high_level_int)
NODE_CLASS_MAPPINGS = { NODE_CLASS_MAPPINGS = {
"INTConstant": INTConstant, "INTConstant": INTConstant,

View File

@ -36,8 +36,10 @@ app.registerExtension({
let animationFrameId; let animationFrameId;
let analyser; let analyser;
let dataArray; let dataArray;
let lowRangeHz; let startRangeHz;
let midRangeHz; let endRangeHz;
let smoothingFactor = 0.5;
let smoothedSoundLevel = 0;
// Function to update the widget value in real-time // Function to update the widget value in real-time
const updateWidgetValueInRealTime = () => { const updateWidgetValueInRealTime = () => {
@ -45,47 +47,35 @@ app.registerExtension({
if (analyser && dataArray) { if (analyser && dataArray) {
analyser.getByteFrequencyData(dataArray); analyser.getByteFrequencyData(dataArray);
const startRangeHzWidget = this.widgets.find(w => w.name === "start_range_hz");
if (startRangeHzWidget) startRangeHz = startRangeHzWidget.value;
const endRangeHzWidget = this.widgets.find(w => w.name === "end_range_hz");
if (endRangeHzWidget) endRangeHz = endRangeHzWidget.value;
const smoothingFactorWidget = this.widgets.find(w => w.name === "smoothing_factor");
if (smoothingFactorWidget) smoothingFactor = smoothingFactorWidget.value;
// Calculate frequency bin width (frequency resolution) // Calculate frequency bin width (frequency resolution)
const frequencyBinWidth = audioContext.sampleRate / analyser.fftSize; const frequencyBinWidth = audioContext.sampleRate / analyser.fftSize;
// Convert the widget values from Hz to indices // Convert the widget values from Hz to indices
const lowRangeIndex = Math.floor(lowRangeHz / frequencyBinWidth); const startRangeIndex = Math.floor(startRangeHz / frequencyBinWidth);
const midRangeIndex = Math.floor(midRangeHz / frequencyBinWidth); const endRangeIndex = Math.floor(endRangeHz / frequencyBinWidth);
// Define frequency ranges for low, mid, and high
const frequencyRanges = {
low: { start: 0, end: lowRangeIndex },
mid: { start: lowRangeIndex, end: midRangeIndex },
high: { start: midRangeIndex, end: dataArray.length }
};
const lowRangeHzWidget = this.widgets.find(w => w.name === "low_range_hz");
if (lowRangeHzWidget) lowRangeHz = lowRangeHzWidget.value;
const midRangeHzWidget = this.widgets.find(w => w.name === "mid_range_hz");
if (midRangeHzWidget) midRangeHz = midRangeHzWidget.value;
// Function to calculate the average value for a frequency range // Function to calculate the average value for a frequency range
const calculateAverage = (start, end) => { const calculateAverage = (start, end) => {
const sum = dataArray.slice(start, end).reduce((acc, val) => acc + val, 0); const sum = dataArray.slice(start, end).reduce((acc, val) => acc + val, 0);
return sum / (end - start); const average = sum / (end - start);
// Apply exponential moving average smoothing
smoothedSoundLevel = (average * (1 - smoothingFactor)) + (smoothedSoundLevel * smoothingFactor);
return smoothedSoundLevel;
}; };
// Calculate the average levels for each frequency range // Calculate the average levels for each frequency range
const lowLevel = calculateAverage(frequencyRanges.low.start, frequencyRanges.low.end); const soundLevel = calculateAverage(startRangeIndex, endRangeIndex);
const midLevel = calculateAverage(frequencyRanges.low.end, frequencyRanges.mid.end); // mid starts where low ends
const highLevel = calculateAverage(frequencyRanges.mid.end, frequencyRanges.high.end); // high starts where mid ends
const averageLevel = dataArray.reduce((sum, averageLevel) => sum + averageLevel, 0) / dataArray.length;
// Update the widget values // Update the widget values
const averageLevelWidget = this.widgets.find(w => w.name === "average_level");
if (averageLevelWidget) averageLevelWidget.value = averageLevel;
const lowLevelWidget = this.widgets.find(w => w.name === "low_level"); const lowLevelWidget = this.widgets.find(w => w.name === "sound_level");
if (lowLevelWidget) lowLevelWidget.value = lowLevel; if (lowLevelWidget) lowLevelWidget.value = soundLevel;
const midLevelWidget = this.widgets.find(w => w.name === "mid_level");
if (midLevelWidget) midLevelWidget.value = midLevel;
const highLevelWidget = this.widgets.find(w => w.name === "high_level");
if (highLevelWidget) highLevelWidget.value = highLevel;
animationFrameId = requestAnimationFrame(updateWidgetValueInRealTime); animationFrameId = requestAnimationFrame(updateWidgetValueInRealTime);
} }
@ -103,10 +93,10 @@ app.registerExtension({
dataArray = new Uint8Array(analyser.frequencyBinCount); dataArray = new Uint8Array(analyser.frequencyBinCount);
// Get the range values from widgets (assumed to be in Hz) // Get the range values from widgets (assumed to be in Hz)
const lowRangeWidget = this.widgets.find(w => w.name === "low_range_hz"); const lowRangeWidget = this.widgets.find(w => w.name === "low_range_hz");
if (lowRangeWidget) lowRangeHz = lowRangeWidget.value; if (lowRangeWidget) startRangeHz = lowRangeWidget.value;
const midRangeWidget = this.widgets.find(w => w.name === "mid_range_hz"); const midRangeWidget = this.widgets.find(w => w.name === "mid_range_hz");
if (midRangeWidget) midRangeHz = midRangeWidget.value; if (midRangeWidget) endRangeHz = midRangeWidget.value;
} }
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => { navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {