added unbatch node & audio duration_list input

This commit is contained in:
SayanoAI
2024-08-05 01:13:10 -04:00
parent c871332dae
commit c877b8c770
3 changed files with 47 additions and 9 deletions
+5 -3
View File
@@ -3,7 +3,7 @@ from .custom_nodes.uvr import UVR5Node
from .custom_nodes.rvc import RVCNode
from .custom_nodes.loaders import DownloadAudio, LoadAudio, LoadWhisperModelNode, LoadRVCModelNode, LoadHubertModel, LoadPitchExtractionParams
from .custom_nodes.output import PreviewAudio
from .custom_nodes.utils import Any2ListNode, AudioBatchValueNode, MergeImageBatches, MergeLatentBatches, ImageRepeatInterleavedNode, LatentRepeatInterleavedNode, MergeAudioNode, SimpleMathNode, SliceNode, ZipImagesNode
from .custom_nodes.utils import Any2ListNode, AudioBatchValueNode, List2AnyNode, MergeImageBatches, MergeLatentBatches, ImageRepeatInterleavedNode, LatentRepeatInterleavedNode, MergeAudioNode, SimpleMathNode, SliceNode, ZipImagesNode
# Set the web directory, any .js file in that directory will be loaded by the frontend as a frontend extension
WEB_DIRECTORY = "./web"
@@ -31,7 +31,8 @@ NODE_CLASS_MAPPINGS = {
"SimpleMathNode": SimpleMathNode,
"SliceNode": SliceNode,
"ZipNode": ZipImagesNode,
"Any2ListNode": Any2ListNode
"Any2ListNode": Any2ListNode,
"List2AnyNode": List2AnyNode
}
# A dictionary that contains the friendly/humanly readable titles for the nodes
@@ -56,5 +57,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"SimpleMathNode": "🌺Simple Math Operations",
"SliceNode": "🌺Slice Array",
"ZipNode": "🌺Zip Images",
"Any2ListNode": "🌺Any to List"
"Any2ListNode": "🌺Any to List",
"List2AnyNode": "🌺List to Any",
}
+35 -6
View File
@@ -168,14 +168,14 @@ class AudioBatchValueNode:
return {
"required": {
"audio": ('VHS_AUDIO',),
"num_segments": ('INT', {"min": 1, "max": 128, "step": 1, "forceInput": True}),
"num_segments": ('INT', {"min": 2, "max": 128, "step": 1, "forceInput": True}),
"output_min": ('FLOAT', {'default': 0., "min": -1000., "max": 1000., "step": .01}),
"output_max": ('FLOAT', {'default': 1., "min": 0., "max": 1000., "step": .01}),
"norm": (["scale","tanh","sigmoid"], {"default": "scale"}),
},
"optional": {
"silence_threshold": ("INT", {"default": 1000, "min": 1, "max": MAX_INT16, "step": 1, "display": "slider"}),
"frame_multiplier": ("INT", {"default": 1, "min": 1, "max": 120, "step": 1}),
"duration_list": ("INT", {"default": None, "min": 1, "forceInput": True}),
"print_output": ("BOOLEAN", {"default": False}),
"inverse": ("BOOLEAN", {"default": False}),
}
@@ -193,12 +193,12 @@ class AudioBatchValueNode:
return np.sqrt(np.nanmean(audio**2))
def get_frame_weights(self, audio, num_segments, output_min, output_max, norm,
silence_threshold=1000, frame_multiplier=1, print_output=False, inverse=False):
silence_threshold=1000, duration_list=None, print_output=False, inverse=False):
assert output_max>=output_min, f"{output_max=} must be greater or equal to {output_min=}!"
audio_data = bytes_to_audio(audio())
audio,_ = remix_audio(audio_data,norm=True,to_int16=True)
num_values = int(num_segments*frame_multiplier)
num_values = int(num_segments)
audio_rms = np.nan_to_num(list(map(self.get_rms,np.array_split(audio.flatten()/silence_threshold, num_values))),nan=0)
audio_zscore = (audio_rms-audio_rms.mean())/audio_rms.std()
output_range = output_max-output_min
@@ -221,7 +221,16 @@ class AudioBatchValueNode:
if print_output:
print(f"{audio_rms.min()=} {audio_rms.max()=} {audio_rms.mean()=} {len(audio_rms)=}")
print(f"{x_norm.min()=} {x_norm.max()=} {x_norm.mean()=} {len(x_norm)=}")
return (list(x_norm),list(map(int,x_norm)),num_values)
if duration_list is not None:
segments = np.cumsum(duration_list)
x_norm = np.array_split(x_norm,segments)
x_norm = map(list,x_norm)
x_norm_int = [list(map(int,norms)) for norms in x_norm]
else:
x_norm_int = map(int,x_norm)
return (list(x_norm),list(x_norm_int),num_values)
class ImageRepeatInterleavedNode:
@classmethod
@@ -519,4 +528,24 @@ class Any2ListNode:
CATEGORY = CATEGORY
def to(self, any):
return (list(any),)
return (list(any),)
class List2AnyNode:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"any": (AlwaysEqualProxy("*"),),
},
}
RETURN_TYPES = (AlwaysEqualProxy("*"),)
INPUT_IS_LIST = (True, )
FUNCTION = "to"
CATEGORY = CATEGORY
def to(self, any):
return (any,)
+7
View File
@@ -316,6 +316,13 @@ app.registerExtension({
})
break;
case "List2AnyNode":
chainCallback(nodeType.prototype, "onConnectInput", function (_, inputs) {
this.outputs[0].name = inputs;
this.outputs[0].type = inputs;
})
break;
default:
break