Merge pull request #110 from Runware/feature-UpdateAudioInferenceSettings
Added new parameters to Runware Audio Inference Settings node
This commit is contained in:
+53
-7
@@ -8,6 +8,9 @@ const TIMEOUT_RANGE = { min: 5, default: 90, max: 99 };
|
||||
const OUTPUT_QUALITY_RANGE = { min: 20, default: 95, max: 99 };
|
||||
const CACHE_SIZE_RANGE = { min: 30, default: 150, max: 4096 };
|
||||
|
||||
/** Must match `audioInferenceInputs.MAX_VIDEOS` in modules/audioInferenceInputs.py */
|
||||
const AUDIO_INFERENCE_INPUTS_MAX_VIDEOS = 4;
|
||||
|
||||
let openDialog = false;
|
||||
let lastTimeout = false;
|
||||
let lastOutputFormat = false;
|
||||
@@ -1173,6 +1176,20 @@ function audioSettingsToggleHandler(settingsNode) {
|
||||
const turboWidget = settingsNode.widgets.find(w => w && w.name === "turbo");
|
||||
const useTextNormalizationWidget = settingsNode.widgets.find(w => w && w.name === "useTextNormalization");
|
||||
const textNormalizationWidget = settingsNode.widgets.find(w => w && w.name === "textNormalization");
|
||||
const useBpmWidget = settingsNode.widgets.find(w => w && w.name === "useBpm");
|
||||
const bpmWidget = settingsNode.widgets.find(w => w && w.name === "bpm");
|
||||
const useKeyScaleWidget = settingsNode.widgets.find(w => w && w.name === "useKeyScale");
|
||||
const keyScaleWidget = settingsNode.widgets.find(w => w && w.name === "keyScale");
|
||||
const useTimeSignatureWidget = settingsNode.widgets.find(w => w && w.name === "useTimeSignature");
|
||||
const timeSignatureWidget = settingsNode.widgets.find(w => w && w.name === "timeSignature");
|
||||
const useVocalLanguageWidget = settingsNode.widgets.find(w => w && w.name === "useVocalLanguage");
|
||||
const vocalLanguageWidget = settingsNode.widgets.find(w => w && w.name === "vocalLanguage");
|
||||
const useCoverConditioningScaleWidget = settingsNode.widgets.find(w => w && w.name === "useCoverConditioningScale");
|
||||
const coverConditioningScaleWidget = settingsNode.widgets.find(w => w && w.name === "coverConditioningScale");
|
||||
const useRepaintingStartWidget = settingsNode.widgets.find(w => w && w.name === "useRepaintingStart");
|
||||
const repaintingStartWidget = settingsNode.widgets.find(w => w && w.name === "repaintingStart");
|
||||
const useRepaintingEndWidget = settingsNode.widgets.find(w => w && w.name === "useRepaintingEnd");
|
||||
const repaintingEndWidget = settingsNode.widgets.find(w => w && w.name === "repaintingEnd");
|
||||
|
||||
function toggleWidgetState(useWidget, paramWidget, paramName) {
|
||||
if (!useWidget || !paramWidget) return;
|
||||
@@ -1196,6 +1213,13 @@ function audioSettingsToggleHandler(settingsNode) {
|
||||
if (useLanguageBoostWidget && languageBoostWidget) toggleWidgetState(useLanguageBoostWidget, languageBoostWidget, "languageBoost");
|
||||
if (useTurboWidget && turboWidget) toggleWidgetState(useTurboWidget, turboWidget, "turbo");
|
||||
if (useTextNormalizationWidget && textNormalizationWidget) toggleWidgetState(useTextNormalizationWidget, textNormalizationWidget, "textNormalization");
|
||||
if (useBpmWidget && bpmWidget) toggleWidgetState(useBpmWidget, bpmWidget, "bpm");
|
||||
if (useKeyScaleWidget && keyScaleWidget) toggleWidgetState(useKeyScaleWidget, keyScaleWidget, "keyScale");
|
||||
if (useTimeSignatureWidget && timeSignatureWidget) toggleWidgetState(useTimeSignatureWidget, timeSignatureWidget, "timeSignature");
|
||||
if (useVocalLanguageWidget && vocalLanguageWidget) toggleWidgetState(useVocalLanguageWidget, vocalLanguageWidget, "vocalLanguage");
|
||||
if (useCoverConditioningScaleWidget && coverConditioningScaleWidget) toggleWidgetState(useCoverConditioningScaleWidget, coverConditioningScaleWidget, "coverConditioningScale");
|
||||
if (useRepaintingStartWidget && repaintingStartWidget) toggleWidgetState(useRepaintingStartWidget, repaintingStartWidget, "repaintingStart");
|
||||
if (useRepaintingEndWidget && repaintingEndWidget) toggleWidgetState(useRepaintingEndWidget, repaintingEndWidget, "repaintingEnd");
|
||||
}
|
||||
|
||||
function videoSettingsToggleHandler(settingsNode) {
|
||||
@@ -2797,6 +2821,8 @@ function audioModelSearchFilterHandler(audioModelSearchNode) {
|
||||
],
|
||||
"Ace": [
|
||||
"runware:ace-step@0 (ACE Step v1 3.5B)",
|
||||
"runware:ace-step@v1.5-base (ACE-Step v1.5 Base)",
|
||||
"runware:ace-step@v1.5-turbo (ACE-Step v1.5 Turbo)",
|
||||
],
|
||||
"Dia": [
|
||||
"runware:dia@v1.0 (Dia 1.6B)",
|
||||
@@ -4116,10 +4142,14 @@ function regionalPromptingRegionsToggleHandler(regionsNode) {
|
||||
}
|
||||
|
||||
function audioInferenceInputsToggleHandler(audioInputsNode) {
|
||||
if (!audioInputsNode?.widgets) return;
|
||||
|
||||
// Find widgets
|
||||
const useVideoWidget = audioInputsNode.widgets.find(w => w.name === "useVideo");
|
||||
const videoWidget = audioInputsNode.widgets.find(w => w.name === "Video");
|
||||
const useVideosWidget = audioInputsNode.widgets.find(w => w.name === "useVideos");
|
||||
const useAudioWidget = audioInputsNode.widgets.find(w => w && w.name === "useAudio");
|
||||
const audioWidget = audioInputsNode.widgets.find(w => w && w.name === "Audio");
|
||||
const useVideoWidget = audioInputsNode.widgets.find(w => w && w.name === "useVideo");
|
||||
const videoWidget = audioInputsNode.widgets.find(w => w && w.name === "Video");
|
||||
const useVideosWidget = audioInputsNode.widgets.find(w => w && w.name === "useVideos");
|
||||
|
||||
// Helper function to toggle widget enabled state
|
||||
function toggleWidgetState(useWidget, paramWidget, paramName) {
|
||||
@@ -4163,18 +4193,34 @@ function audioInferenceInputsToggleHandler(audioInputsNode) {
|
||||
setTimeout(toggleEnabled, 100);
|
||||
}
|
||||
|
||||
// Set up toggle handler for single audio
|
||||
if (useAudioWidget && audioWidget) {
|
||||
toggleWidgetState(useAudioWidget, audioWidget, "Audio");
|
||||
}
|
||||
|
||||
// Set up toggle handler for single video
|
||||
if (useVideoWidget && videoWidget) {
|
||||
toggleWidgetState(useVideoWidget, videoWidget, "Video");
|
||||
}
|
||||
|
||||
// Set up toggle handlers for multiple videos (Video1, Video2, Video3, Video4)
|
||||
// Set up toggle handlers for multiple videos (Video1 … VideoN; N from widgets, fallback to AUDIO_INFERENCE_INPUTS_MAX_VIDEOS)
|
||||
if (useVideosWidget) {
|
||||
function getAudioInferenceVideoSlotCount() {
|
||||
let max = 0;
|
||||
for (const w of audioInputsNode.widgets) {
|
||||
if (!w?.name) continue;
|
||||
const m = /^Video(\d+)$/.exec(w.name);
|
||||
if (m) max = Math.max(max, parseInt(m[1], 10));
|
||||
}
|
||||
return max > 0 ? max : AUDIO_INFERENCE_INPUTS_MAX_VIDEOS;
|
||||
}
|
||||
|
||||
function toggleVideosEnabled() {
|
||||
const enabled = useVideosWidget.value === true;
|
||||
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
const videoWidget = audioInputsNode.widgets.find(w => w.name === `Video${i}`);
|
||||
const slotCount = getAudioInferenceVideoSlotCount();
|
||||
|
||||
for (let i = 1; i <= slotCount; i++) {
|
||||
const videoWidget = audioInputsNode.widgets.find(w => w && w.name === `Video${i}`);
|
||||
if (videoWidget) {
|
||||
if (videoWidget.inputEl) {
|
||||
videoWidget.inputEl.disabled = !enabled;
|
||||
|
||||
@@ -10,6 +10,14 @@ class audioInferenceInputs:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
optionalInputs = {
|
||||
"useAudio": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include single audio input in API request.",
|
||||
"default": False,
|
||||
}),
|
||||
"Audio": ("STRING", {
|
||||
"tooltip": "Audio URL or mediaUUID for audio generation. Can be a direct URL or a mediaUUID from Runware Media Upload node. Only used when 'Use Audio' is enabled.",
|
||||
"default": "",
|
||||
}),
|
||||
"useVideo": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include single video input in API request.",
|
||||
"default": False,
|
||||
@@ -37,7 +45,7 @@ class audioInferenceInputs:
|
||||
"optional": optionalInputs
|
||||
}
|
||||
|
||||
DESCRIPTION = "Configure custom inputs for Runware Audio Inference, including single or multiple video inputs for audio extraction or generation."
|
||||
DESCRIPTION = "Configure custom inputs for Runware Audio Inference, including optional audio URL/mediaUUID, and single or multiple video inputs for audio extraction or generation."
|
||||
FUNCTION = "createInputs"
|
||||
RETURN_TYPES = ("RUNWAREAUDIOINFERENCEINPUTS",)
|
||||
RETURN_NAMES = ("Audio Inference Inputs",)
|
||||
@@ -45,12 +53,18 @@ class audioInferenceInputs:
|
||||
|
||||
def createInputs(self, **kwargs) -> tuple[Dict[str, Any]]:
|
||||
"""Create audio inference inputs from provided parameters"""
|
||||
useAudio = kwargs.get("useAudio", False)
|
||||
audio = kwargs.get("Audio", None)
|
||||
useVideo = kwargs.get("useVideo", False)
|
||||
video = kwargs.get("Video", None)
|
||||
useVideos = kwargs.get("useVideos", False)
|
||||
|
||||
inputs = {}
|
||||
|
||||
|
||||
# Handle single audio (inputs.audio)
|
||||
if useAudio and audio is not None and audio.strip() != "":
|
||||
inputs["audio"] = audio.strip()
|
||||
|
||||
# Handle single video (inputs.video)
|
||||
if useVideo and video is not None and video.strip() != "":
|
||||
inputs["video"] = video.strip()
|
||||
|
||||
@@ -16,6 +16,8 @@ class RunwareAudioModelSearch:
|
||||
],
|
||||
"Ace": [
|
||||
"runware:ace-step@0 (ACE Step v1 3.5B)",
|
||||
"runware:ace-step@v1.5-base (ACE-Step v1.5 Base)",
|
||||
"runware:ace-step@v1.5-turbo (ACE-Step v1.5 Turbo)",
|
||||
],
|
||||
"Dia": [
|
||||
"runware:dia@v1.0 (Dia 1.6B)",
|
||||
|
||||
+115
-5
@@ -1,14 +1,22 @@
|
||||
"""
|
||||
Runware Audio Inference Settings Node
|
||||
Provides lyrics, guidanceType, languageBoost, turbo, temperature, and textNormalization
|
||||
settings for Runware Audio Inference.
|
||||
Provides lyrics, guidanceType, languageBoost, turbo, temperature, textNormalization,
|
||||
bpm, keyScale, timeSignature, vocalLanguage, coverConditioningScale, repaintingStart,
|
||||
and repaintingEnd for Runware Audio Inference.
|
||||
"""
|
||||
|
||||
from typing import Dict, Any
|
||||
|
||||
_VOCAL_LANGUAGE_CODES = [
|
||||
"ar", "az", "bg", "bn", "ca", "cs", "da", "de", "el", "en", "es", "fa", "fi", "fr",
|
||||
"he", "hi", "hr", "ht", "hu", "id", "is", "it", "ja", "ko", "la", "lt", "ms", "ne",
|
||||
"nl", "no", "pa", "pl", "pt", "ro", "ru", "sa", "sk", "sr", "sv", "sw", "ta", "te",
|
||||
"th", "tl", "tr", "uk", "ur", "vi", "yue", "zh", "unknown",
|
||||
]
|
||||
|
||||
|
||||
class RunwareAudioSettings:
|
||||
"""Runware Audio Inference Settings Node (lyrics, guidanceType, languageBoost, turbo, temperature, textNormalization)."""
|
||||
"""Runware Audio Inference Settings Node."""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -41,7 +49,7 @@ class RunwareAudioSettings:
|
||||
"default": False,
|
||||
}),
|
||||
"guidanceType": (["apg", "cfg"], {
|
||||
"tooltip": "Controls how the guidance value is used. apg = Adversarial Perceptual Guidance, cfg = Classifier-Free Guidance",
|
||||
"tooltip": "Controls how the guidance value is used. See API GuidanceType: apg | cfg.",
|
||||
"default": "apg",
|
||||
}),
|
||||
"useLanguageBoost": ("BOOLEAN", {
|
||||
@@ -76,6 +84,73 @@ class RunwareAudioSettings:
|
||||
"label_on": "true",
|
||||
"label_off": "false",
|
||||
}),
|
||||
"useBpm": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include bpm (tempo) in audio generation settings. If disabled, the model decides automatically.",
|
||||
"default": False,
|
||||
}),
|
||||
"bpm": ("INT", {
|
||||
"tooltip": "Beats per minute (30–300). If not set via API, the model decides. Common: 60–80 ballad, 90–110 pop, 120–130 house, 140–170 DnB. Only used when 'Use Bpm' is enabled.",
|
||||
"default": 120,
|
||||
"min": 30,
|
||||
"max": 300,
|
||||
"step": 1,
|
||||
}),
|
||||
"useKeyScale": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include keyScale (musical key and scale). Empty value lets the model decide.",
|
||||
"default": False,
|
||||
}),
|
||||
"keyScale": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "Musical key and scale. Empty string lets the model decide. Format: '{Note}{Accidental} {Mode}' (Note A–G, Accidental '' | '#' | 'b' | '♯' | '♭', Mode 'major' | 'minor'). Examples: 'C major', 'F# minor', 'B♭ major'.",
|
||||
}),
|
||||
"useTimeSignature": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include timeSignature (beats per measure). If disabled, the model decides automatically.",
|
||||
"default": False,
|
||||
}),
|
||||
"timeSignature": ("INT", {
|
||||
"default": 4,
|
||||
"min": 1,
|
||||
"max": 32,
|
||||
"step": 1,
|
||||
"tooltip": "Time signature as integer beats per bar (e.g. 2, 3, 4, 6). Only used when 'Use Time Signature' is enabled.",
|
||||
}),
|
||||
"useVocalLanguage": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include vocalLanguage (language code) for vocal generation. See dropdown for available codes.",
|
||||
"default": False,
|
||||
}),
|
||||
"vocalLanguage": (_VOCAL_LANGUAGE_CODES, {
|
||||
"tooltip": "Language code for vocals. Supports values from the dropdown list (including 'yue', 'zh', and 'unknown'). Use 'unknown' for instrumental or automatic detection. Only used when 'Use Vocal Language' is enabled.",
|
||||
"default": "en",
|
||||
}),
|
||||
"useCoverConditioningScale": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include coverConditioningScale (source-audio conditioning fraction for cover tasks). Only effective when input audio is provided.",
|
||||
"default": False,
|
||||
}),
|
||||
"coverConditioningScale": ("FLOAT", {
|
||||
"tooltip": "Fraction of denoising steps using source-audio conditioning (cover task). 1.0 = all steps; 0.5 = first half source then text-only. Only used when 'Use Cover Conditioning Scale' is enabled.",
|
||||
"default": 1.0,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01,
|
||||
}),
|
||||
"useRepaintingStart": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include repaintingStart (seconds). Requires input audio. Sets repaint region with repaintingEnd; negative values prepend (outpaint before start).",
|
||||
"default": False,
|
||||
}),
|
||||
"repaintingStart": ("FLOAT", {
|
||||
"tooltip": "Start time in seconds for repaint/inpaint/outpaint region. Only used when 'Use Repainting Start' is enabled.",
|
||||
"default": 0.0,
|
||||
"step": 0.01,
|
||||
}),
|
||||
"useRepaintingEnd": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include repaintingEnd (seconds). Requires input audio. Values beyond source duration append (outpaint).",
|
||||
"default": False,
|
||||
}),
|
||||
"repaintingEnd": ("FLOAT", {
|
||||
"tooltip": "End time in seconds for repaint region. Only used when 'Use Repainting End' is enabled.",
|
||||
"default": 0.0,
|
||||
"step": 0.01,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +158,7 @@ class RunwareAudioSettings:
|
||||
RETURN_NAMES = ("settings",)
|
||||
FUNCTION = "createSettings"
|
||||
CATEGORY = "Runware/Audio"
|
||||
DESCRIPTION = "Configure audio generation settings (lyrics, guidanceType, languageBoost, turbo, temperature, textNormalization) for Runware Audio Inference. Connect to Runware Audio Inference node."
|
||||
DESCRIPTION = "Configure audio generation settings (lyrics, guidanceType, languageBoost, turbo, temperature, textNormalization, bpm, keyScale, timeSignature, vocalLanguage, coverConditioningScale, repaintingStart, repaintingEnd) for Runware Audio Inference. Connect to Runware Audio Inference node."
|
||||
|
||||
def createSettings(self, **kwargs) -> tuple[Dict[str, Any]]:
|
||||
"""Create audio settings dict for API"""
|
||||
@@ -99,6 +174,20 @@ class RunwareAudioSettings:
|
||||
turbo = kwargs.get("turbo", False)
|
||||
use_text_normalization = kwargs.get("useTextNormalization", False)
|
||||
text_normalization = kwargs.get("textNormalization", True)
|
||||
use_bpm = kwargs.get("useBpm", False)
|
||||
bpm = kwargs.get("bpm", 120)
|
||||
use_key_scale = kwargs.get("useKeyScale", False)
|
||||
key_scale = kwargs.get("keyScale", "")
|
||||
use_time_signature = kwargs.get("useTimeSignature", False)
|
||||
time_signature = kwargs.get("timeSignature", 4)
|
||||
use_vocal_language = kwargs.get("useVocalLanguage", False)
|
||||
vocal_language = kwargs.get("vocalLanguage", "en")
|
||||
use_cover_conditioning_scale = kwargs.get("useCoverConditioningScale", False)
|
||||
cover_conditioning_scale = kwargs.get("coverConditioningScale", 1.0)
|
||||
use_repainting_start = kwargs.get("useRepaintingStart", False)
|
||||
repainting_start = kwargs.get("repaintingStart", 0.0)
|
||||
use_repainting_end = kwargs.get("useRepaintingEnd", False)
|
||||
repainting_end = kwargs.get("repaintingEnd", 0.0)
|
||||
|
||||
settings: Dict[str, Any] = {}
|
||||
|
||||
@@ -120,6 +209,27 @@ class RunwareAudioSettings:
|
||||
if use_text_normalization:
|
||||
settings["textNormalization"] = bool(text_normalization)
|
||||
|
||||
if use_bpm:
|
||||
settings["bpm"] = int(bpm)
|
||||
|
||||
if use_key_scale and str(key_scale).strip():
|
||||
settings["keyScale"] = str(key_scale).strip()
|
||||
|
||||
if use_time_signature:
|
||||
settings["timeSignature"] = int(time_signature)
|
||||
|
||||
if use_vocal_language:
|
||||
settings["vocalLanguage"] = vocal_language
|
||||
|
||||
if use_cover_conditioning_scale:
|
||||
settings["coverConditioningScale"] = float(cover_conditioning_scale)
|
||||
|
||||
if use_repainting_start:
|
||||
settings["repaintingStart"] = float(repainting_start)
|
||||
|
||||
if use_repainting_end:
|
||||
settings["repaintingEnd"] = float(repainting_end)
|
||||
|
||||
return (settings,)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user