Added inital nodes code
This commit is contained in:
+6
-3
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user