added unbatch node & audio duration_list input
This commit is contained in:
+5
-3
@@ -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
@@ -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,)
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user