Added inital nodes code

This commit is contained in:
Brody Childs
2024-01-12 18:10:49 -05:00
parent 55d82bbe66
commit c2adfd2976
3 changed files with 69 additions and 19 deletions
+6 -3
View File
@@ -1,19 +1,22 @@
# MBM's Music Visualizer
# Imports
from mbmMusicVisualizer import MusicVisualizer
from .mbmMusicVisualizer import MusicVisualizer
from .mbmAudioLoader import AudioLoader
# A dictionary that contains all nodes you want to export with their names
# NOTE: names should be globally unique
NODE_CLASS_MAPPINGS = {
# "id": Class
"mbmMusicVisuzalizer": MusicVisualizer
"mbmMusicVisuzalizer": MusicVisualizer,
"mbmAudioLoader": AudioLoader
}
# A dictionary that contains the friendly/humanly readable titles for the nodes
NODE_DISPLAY_NAME_MAPPINGS = {
# "id": "readable"
"mbmMusicVisuzalizer": "Music Visualizer"
"mbmMusicVisuzalizer": "Music Visualizer",
"mbmAudioLoader": "Audio Loader"
}
# Export
+15 -8
View File
@@ -3,10 +3,12 @@
# Imports
import os
import mbmMVShared as mvs
import librosa
from .mbmMVShared import fullpath, audioInputDir
# Classes
class MusicVisualizer:
class AudioLoader:
"""
Load an audio file.
"""
@@ -15,17 +17,22 @@ class MusicVisualizer:
@classmethod
def INPUT_TYPES(s):
inputDir = mvs.audioInputDir()
inputDir = audioInputDir()
localFiles = [f for f in os.listdir(inputDir) if os.path.isfile(os.path.join(inputDir, f))]
return {
"required": {
"file": (sorted(localFiles), {"image_upload": True}),
"file": (sorted(localFiles),) # TODO: add more params?
}
}
RETURN_TYPES = ("AUDIO", )
RETURN_TYPES = ("AUDIO", "STRING")
RETURN_NAMES = ("AUDIO", "FILENAME")
FUNCTION = "process"
CATEGORY = "MBMnodes"
CATEGORY = "MBMnodes/MusicVisualizer"
def process(self):
return None
def process(self, filepath: str):
return (
librosa.load(fullpath(filepath)),
os.path.splitext(os.path.basename(filepath))[0]
)
+48 -8
View File
@@ -2,7 +2,8 @@
# Visualize a provided audio file.
# Imports
# etc
import librosa
import numpy as np
# Classes
class MusicVisualizer:
@@ -18,7 +19,7 @@ class MusicVisualizer:
def INPUT_TYPES(s):
return {
"required": {
"audio": "AUDIO",
"audio": ("AUDIO",),
"width": ("INT", {"default": 512}),
"height": ("INT", {"default": 512}),
"pitch": ("INT", {"default": 220}), # sensitivity
@@ -27,23 +28,62 @@ class MusicVisualizer:
"jitter": ("FLOAT", {"default": 0.5}),
"truncation": ("FLOAT", {"default": 1.0}),
"smoothing": ("INT", {"default": 20}), # factor
"hopLength": ("INT", {"default": 512}),
}
}
RETURN_TYPES = ("IMAGE", )
RETURN_NAMES = ("IMAGES", )
FUNCTION = "process"
CATEGORY = "MBMnodes"
CATEGORY = "MBMnodes/MusicVisualizer"
def process(self,
audio,
audio: tuple,
width: int,
height: int,
pitch: int,
tempo: int,
pitchSensitivity: int,
tempoSensitivity: int,
depth: float,
jitter: float,
truncation: float,
smoothing: int
smoothFactor: int,
hopLen: int
):
return None
# Unpack the audio
y, sr = audio
# Calculate parameters
pitchSensitivity = (300 - pitchSensitivity) * 512 / hopLen
tempoSensitivity = tempoSensitivity * hopLen / 512
if smoothFactor > 1:
smoothFactor = int(smoothFactor * 512 / hopLen)
# Calculate the spectrogram
spectro = librosa.feature.melspectrogram(
y=y,
sr=sr,
n_mels=128,
fmax=8000,
hop_length=hopLen
)
# Calculate mean power for hops
spectroMean = np.mean(spectro, axis=0)
# Calculate power gradient for hops
spectroGrad = np.gradient(spectroMean)
spectroGrad = (spectroGrad / np.max(spectroGrad)).clip(min=0)
# Normalize mean power
spectroMean = (spectroMean / np.min(spectroMean)) / np.ptp(spectroMean)
# Calculate pitch chroma for hops
chroma = librosa.feature.chroma_cqt(
y=y,
sr=sr,
hop_length=hopLen
)
# Sort pitch chroma
chromaSort = np.argsort(np.mean(chroma, axis=1))[::-1]