Add files via upload
New effect: Bars Better frequency scaling by modifying parameters in melbank.py Mel graph [before](https://imgur.com/a/xN9PA), [after](https://imgur.com/a/YYGLk) This stretches out the lower end with vocals and bass, and squishes up the high end which usually takes up moer space on the strip for similar "sounds". Now it looks more like you would expect it to, based on what you hear (more pitch-like than frequency)
This commit is contained in:
parent
24289b61ca
commit
5e68b99b28
@ -31,6 +31,7 @@ Functions
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from numpy import abs, append, arange, insert, linspace, log10, round, zeros
|
from numpy import abs, append, arange, insert, linspace, log10, round, zeros
|
||||||
|
from math import log
|
||||||
|
|
||||||
|
|
||||||
def hertz_to_mel(freq):
|
def hertz_to_mel(freq):
|
||||||
@ -44,7 +45,8 @@ def hertz_to_mel(freq):
|
|||||||
mel : scalar or ndarray
|
mel : scalar or ndarray
|
||||||
Mel-frequency value or ndarray in Mel
|
Mel-frequency value or ndarray in Mel
|
||||||
"""
|
"""
|
||||||
return 2595.0 * log10(1 + (freq / 700.0))
|
#return 2595.0 * log10(1 + (freq / 700.0))
|
||||||
|
return 3340.0 * log(1 + (freq / 250.0), 9)
|
||||||
|
|
||||||
|
|
||||||
def mel_to_hertz(mel):
|
def mel_to_hertz(mel):
|
||||||
@ -58,7 +60,8 @@ def mel_to_hertz(mel):
|
|||||||
freq : scalar or ndarray
|
freq : scalar or ndarray
|
||||||
Frequency value or array in Hz.
|
Frequency value or array in Hz.
|
||||||
"""
|
"""
|
||||||
return 700.0 * (10**(mel / 2595.0)) - 700.0
|
#return 700.0 * (10**(mel / 2595.0)) - 700.0
|
||||||
|
return 250.0 * (9**(mel / 3340.0)) - 250.0
|
||||||
|
|
||||||
|
|
||||||
def melfrequencies_mel_filterbank(num_bands, freq_min, freq_max, num_fft_bands):
|
def melfrequencies_mel_filterbank(num_bands, freq_min, freq_max, num_fft_bands):
|
||||||
|
@ -26,6 +26,7 @@ class Visualizer():
|
|||||||
"Wavelength":self.visualize_wavelength,
|
"Wavelength":self.visualize_wavelength,
|
||||||
"Beat":self.visualize_beat,
|
"Beat":self.visualize_beat,
|
||||||
"Wave":self.visualize_wave,
|
"Wave":self.visualize_wave,
|
||||||
|
"Bars":self.visualize_bars,
|
||||||
"Single":self.visualize_single,
|
"Single":self.visualize_single,
|
||||||
"Fade":self.visualize_fade,
|
"Fade":self.visualize_fade,
|
||||||
"Gradient":self.visualize_gradient}
|
"Gradient":self.visualize_gradient}
|
||||||
@ -88,7 +89,7 @@ class Visualizer():
|
|||||||
"color_mode": "Spectral", # Colour mode of overlay
|
"color_mode": "Spectral", # Colour mode of overlay
|
||||||
"mirror": False, # Reflect output down centre of strip
|
"mirror": False, # Reflect output down centre of strip
|
||||||
"reverse_grad": False, # Flip (LR) gradient
|
"reverse_grad": False, # Flip (LR) gradient
|
||||||
"reverse_roll": False, # Reverse movement of gradient
|
"reverse_roll": False, # Reverse movement of gradient roll
|
||||||
"blur": 3.0}, # Amount of blur to apply
|
"blur": 3.0}, # Amount of blur to apply
|
||||||
"Scroll":{"decay": 0.95, # How quickly the colour fades away as it moves
|
"Scroll":{"decay": 0.95, # How quickly the colour fades away as it moves
|
||||||
"blur": 0.2}, # Amount of blur to apply
|
"blur": 0.2}, # Amount of blur to apply
|
||||||
@ -96,8 +97,14 @@ class Visualizer():
|
|||||||
"Single":{"color": "Red"}, # Static color to show
|
"Single":{"color": "Red"}, # Static color to show
|
||||||
"Beat":{"color": "Red", # Colour of beat flash
|
"Beat":{"color": "Red", # Colour of beat flash
|
||||||
"decay": 0.7}, # How quickly the flash fades away
|
"decay": 0.7}, # How quickly the flash fades away
|
||||||
|
"Bars":{"resolution":4, # Number of "bars"
|
||||||
|
"color_mode":"Spectral", # Multicolour mode to use
|
||||||
|
"roll_speed":0, # How fast (if at all) to cycle colour colours across strip
|
||||||
|
"mirror": False, # Mirror down centre of strip
|
||||||
|
#"reverse_grad": False, # Flip (LR) gradient
|
||||||
|
"reverse_roll": False}, # Reverse movement of gradient roll
|
||||||
"Gradient":{"color_mode":"Spectral", # Colour gradient to display
|
"Gradient":{"color_mode":"Spectral", # Colour gradient to display
|
||||||
"roll_speed": 0, # How fast (if at all) to cycle colour overlay across strip
|
"roll_speed": 0, # How fast (if at all) to cycle colour colours across strip
|
||||||
"mirror": False, # Mirror gradient down central axis
|
"mirror": False, # Mirror gradient down central axis
|
||||||
"reverse": False}, # Reverse movement of gradient
|
"reverse": False}, # Reverse movement of gradient
|
||||||
"Fade":{"color_mode":"Spectral", # Colour gradient to fade through
|
"Fade":{"color_mode":"Spectral", # Colour gradient to fade through
|
||||||
@ -150,6 +157,11 @@ class Visualizer():
|
|||||||
"Single":[["color", "Color", "dropdown", self.colors]],
|
"Single":[["color", "Color", "dropdown", self.colors]],
|
||||||
"Beat":[["color", "Color", "dropdown", self.colors],
|
"Beat":[["color", "Color", "dropdown", self.colors],
|
||||||
["decay", "Flash Decay", "float_slider", (0.3,0.98,0.005)]],
|
["decay", "Flash Decay", "float_slider", (0.3,0.98,0.005)]],
|
||||||
|
"Bars":[["color_mode", "Color Mode", "dropdown", self.multicolor_mode_names],
|
||||||
|
["resolution", "Resolution", "slider", (1, config.N_FFT_BINS, 1)],
|
||||||
|
["roll_speed", "Roll Speed", "slider", (0,8,1)],
|
||||||
|
["mirror", "Mirror", "checkbox"],
|
||||||
|
["reverse_roll", "Reverse Roll", "checkbox"]],
|
||||||
"Gradient":[["color_mode", "Color Mode", "dropdown", self.multicolor_mode_names],
|
"Gradient":[["color_mode", "Color Mode", "dropdown", self.multicolor_mode_names],
|
||||||
["roll_speed", "Roll Speed", "slider", (0,8,1)],
|
["roll_speed", "Roll Speed", "slider", (0,8,1)],
|
||||||
["mirror", "Mirror", "checkbox"],
|
["mirror", "Mirror", "checkbox"],
|
||||||
@ -175,32 +187,32 @@ class Visualizer():
|
|||||||
_gradient_half = _gradient_whole[::2]
|
_gradient_half = _gradient_whole[::2]
|
||||||
# Spectral colour mode
|
# Spectral colour mode
|
||||||
self.multicolor_modes["Spectral"] = np.zeros((3,config.N_PIXELS))
|
self.multicolor_modes["Spectral"] = np.zeros((3,config.N_PIXELS))
|
||||||
self.multicolor_modes["Spectral"][0, :config.N_PIXELS//2] = _gradient_half[::-1]
|
self.multicolor_modes["Spectral"][2, :config.N_PIXELS//2] = _gradient_half[::-1]
|
||||||
self.multicolor_modes["Spectral"][1, :] = _gradient_half + _gradient_half[::-1]
|
self.multicolor_modes["Spectral"][1, :] = _gradient_half + _gradient_half[::-1]
|
||||||
self.multicolor_modes["Spectral"][2, :] = np.flipud(self.multicolor_modes["Spectral"][0])
|
self.multicolor_modes["Spectral"][0, :] = np.flipud(self.multicolor_modes["Spectral"][2])
|
||||||
# Dancefloor colour mode
|
# Dancefloor colour mode
|
||||||
self.multicolor_modes["Dancefloor"] = np.zeros((3,config.N_PIXELS))
|
self.multicolor_modes["Dancefloor"] = np.zeros((3,config.N_PIXELS))
|
||||||
self.multicolor_modes["Dancefloor"][0, :] = _gradient_whole[::-1]
|
self.multicolor_modes["Dancefloor"][2, :] = _gradient_whole[::-1]
|
||||||
self.multicolor_modes["Dancefloor"][2, :] = _gradient_whole
|
self.multicolor_modes["Dancefloor"][0, :] = _gradient_whole
|
||||||
# Brilliance colour mode
|
# Brilliance colour mode
|
||||||
self.multicolor_modes["Brilliance"] = np.zeros((3,config.N_PIXELS))
|
self.multicolor_modes["Brilliance"] = np.zeros((3,config.N_PIXELS))
|
||||||
self.multicolor_modes["Brilliance"][0, :] = _gradient_whole[::-1]
|
self.multicolor_modes["Brilliance"][2, :] = _gradient_whole[::-1]
|
||||||
self.multicolor_modes["Brilliance"][1, :] = 255
|
self.multicolor_modes["Brilliance"][1, :] = 255
|
||||||
self.multicolor_modes["Brilliance"][2, :] = _gradient_whole
|
self.multicolor_modes["Brilliance"][0, :] = _gradient_whole
|
||||||
# Jungle colour mode
|
# Jungle colour mode
|
||||||
self.multicolor_modes["Jungle"] = np.zeros((3,config.N_PIXELS))
|
self.multicolor_modes["Jungle"] = np.zeros((3,config.N_PIXELS))
|
||||||
self.multicolor_modes["Jungle"][0, :] = _gradient_whole[::-1]
|
self.multicolor_modes["Jungle"][1, :] = _gradient_whole[::-1]
|
||||||
self.multicolor_modes["Jungle"][1, :] = _gradient_whole
|
self.multicolor_modes["Jungle"][0, :] = _gradient_whole
|
||||||
# Sky colour mode
|
# Sky colour mode
|
||||||
self.multicolor_modes["Sky"] = np.zeros((3,config.N_PIXELS))
|
self.multicolor_modes["Sky"] = np.zeros((3,config.N_PIXELS))
|
||||||
self.multicolor_modes["Sky"][0, :config.N_PIXELS//2] = _alt_gradient_half[::-1]
|
self.multicolor_modes["Sky"][1, :config.N_PIXELS//2] = _alt_gradient_half[::-1]
|
||||||
self.multicolor_modes["Sky"][1, config.N_PIXELS//2:] = _alt_gradient_half
|
self.multicolor_modes["Sky"][0, config.N_PIXELS//2:] = _alt_gradient_half
|
||||||
self.multicolor_modes["Sky"][2, :] = 255
|
self.multicolor_modes["Sky"][2, :] = 255
|
||||||
# Acid colour mode
|
# Acid colour mode
|
||||||
self.multicolor_modes["Acid"] = np.zeros((3,config.N_PIXELS))
|
self.multicolor_modes["Acid"] = np.zeros((3,config.N_PIXELS))
|
||||||
self.multicolor_modes["Acid"][0, :config.N_PIXELS//2] = _alt_gradient_half[::-1]
|
self.multicolor_modes["Acid"][2, :config.N_PIXELS//2] = _alt_gradient_half[::-1]
|
||||||
self.multicolor_modes["Acid"][1, :] = 255
|
self.multicolor_modes["Acid"][1, :] = 255
|
||||||
self.multicolor_modes["Acid"][2, config.N_PIXELS//2:] = _alt_gradient_half
|
self.multicolor_modes["Acid"][0, config.N_PIXELS//2:] = _alt_gradient_half
|
||||||
# Ocean colour mode
|
# Ocean colour mode
|
||||||
self.multicolor_modes["Ocean"] = np.zeros((3,config.N_PIXELS))
|
self.multicolor_modes["Ocean"] = np.zeros((3,config.N_PIXELS))
|
||||||
self.multicolor_modes["Ocean"][1, :] = _gradient_whole
|
self.multicolor_modes["Ocean"][1, :] = _gradient_whole
|
||||||
@ -310,17 +322,16 @@ class Visualizer():
|
|||||||
#g = np.abs(diff)
|
#g = np.abs(diff)
|
||||||
b = b_filt.update(np.copy(y))
|
b = b_filt.update(np.copy(y))
|
||||||
r = np.array([j for i in zip(r,r) for j in i])
|
r = np.array([j for i in zip(r,r) for j in i])
|
||||||
#b = np.array([j for i in zip(b,b) for j in i])
|
|
||||||
output = np.array([self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]][0][
|
output = np.array([self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]][0][
|
||||||
(config.N_PIXELS if not self.effect_opts["Wavelength"]["reverse_grad"] else 0):
|
(config.N_PIXELS if self.effect_opts["Wavelength"]["reverse_grad"] else 0):
|
||||||
(None if not self.effect_opts["Wavelength"]["reverse_grad"] else config.N_PIXELS):]*r,
|
(None if self.effect_opts["Wavelength"]["reverse_grad"] else config.N_PIXELS):]*r,
|
||||||
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]][1][
|
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]][1][
|
||||||
(config.N_PIXELS if not self.effect_opts["Wavelength"]["reverse_grad"] else 0):
|
(config.N_PIXELS if self.effect_opts["Wavelength"]["reverse_grad"] else 0):
|
||||||
(None if not self.effect_opts["Wavelength"]["reverse_grad"] else config.N_PIXELS):]*r,
|
(None if self.effect_opts["Wavelength"]["reverse_grad"] else config.N_PIXELS):]*r,
|
||||||
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]][2][
|
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]][2][
|
||||||
(config.N_PIXELS if not self.effect_opts["Wavelength"]["reverse_grad"] else 0):
|
(config.N_PIXELS if self.effect_opts["Wavelength"]["reverse_grad"] else 0):
|
||||||
(None if not self.effect_opts["Wavelength"]["reverse_grad"] else config.N_PIXELS):]*r])
|
(None if self.effect_opts["Wavelength"]["reverse_grad"] else config.N_PIXELS):]*r])
|
||||||
self.prev_spectrum = y
|
#self.prev_spectrum = y
|
||||||
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]] = np.roll(
|
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]] = np.roll(
|
||||||
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]],
|
self.multicolor_modes[self.effect_opts["Wavelength"]["color_mode"]],
|
||||||
self.effect_opts["Wavelength"]["roll_speed"]*(-1 if self.effect_opts["Wavelength"]["reverse_roll"] else 1),
|
self.effect_opts["Wavelength"]["roll_speed"]*(-1 if self.effect_opts["Wavelength"]["reverse_roll"] else 1),
|
||||||
@ -424,7 +435,44 @@ class Visualizer():
|
|||||||
output = np.multiply(self.prev_output,self.effect_opts["Beat"]["decay"])
|
output = np.multiply(self.prev_output,self.effect_opts["Beat"]["decay"])
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def visualize_bars(self, y):
|
||||||
|
# Bit of fiddling with the y values
|
||||||
|
y = np.copy(interpolate(y, config.N_PIXELS // 2))
|
||||||
|
common_mode.update(y)
|
||||||
|
self.prev_spectrum = np.copy(y)
|
||||||
|
# Color channel mappings
|
||||||
|
r = r_filt.update(y - common_mode.value)
|
||||||
|
r = np.array([j for i in zip(r,r) for j in i])
|
||||||
|
# Split y into [resulution] chunks and calculate the average of each
|
||||||
|
max_values = np.array([max(i) for i in np.array_split(r, self.effect_opts["Bars"]["resolution"])])
|
||||||
|
max_values = np.clip(max_values, 0, 1)
|
||||||
|
color_sets = []
|
||||||
|
for i in range(self.effect_opts["Bars"]["resolution"]):
|
||||||
|
# [r,g,b] values from a multicolour gradient array at [resulution] equally spaced intervals
|
||||||
|
color_sets.append([self.multicolor_modes[self.effect_opts["Bars"]["color_mode"]]\
|
||||||
|
[j][i*(config.N_PIXELS//self.effect_opts["Bars"]["resolution"])] for j in range(3)])
|
||||||
|
output = np.zeros((3,config.N_PIXELS))
|
||||||
|
chunks = np.array_split(output[0], self.effect_opts["Bars"]["resolution"])
|
||||||
|
n = 0
|
||||||
|
# Assign blocks with heights corresponding to max_values and colours from color_sets
|
||||||
|
for i in range(len(chunks)):
|
||||||
|
m = len(chunks[i])
|
||||||
|
for j in range(3):
|
||||||
|
output[j][n:n+m] = color_sets[i][j]*max_values[i]
|
||||||
|
n += m
|
||||||
|
self.multicolor_modes[self.effect_opts["Bars"]["color_mode"]] = np.roll(
|
||||||
|
self.multicolor_modes[self.effect_opts["Bars"]["color_mode"]],
|
||||||
|
self.effect_opts["Bars"]["roll_speed"]*(-1 if self.effect_opts["Bars"]["reverse_roll"] else 1),
|
||||||
|
axis=1)
|
||||||
|
if self.effect_opts["Bars"]["mirror"]:
|
||||||
|
output = np.concatenate((output[:, ::-2], output[:, ::2]), axis=1)
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def visualize_single(self, y):
|
def visualize_single(self, y):
|
||||||
|
"Displays a single colour, non audio reactive"
|
||||||
output = np.zeros((3,config.N_PIXELS))
|
output = np.zeros((3,config.N_PIXELS))
|
||||||
output[0][:]=self.colors[self.effect_opts["Single"]["color"]][0]
|
output[0][:]=self.colors[self.effect_opts["Single"]["color"]][0]
|
||||||
output[1][:]=self.colors[self.effect_opts["Single"]["color"]][1]
|
output[1][:]=self.colors[self.effect_opts["Single"]["color"]][1]
|
||||||
@ -432,6 +480,7 @@ class Visualizer():
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
def visualize_gradient(self, y):
|
def visualize_gradient(self, y):
|
||||||
|
"Displays a multicolour gradient, non audio reactive"
|
||||||
output = np.array([self.multicolor_modes[self.effect_opts["Gradient"]["color_mode"]][0][:config.N_PIXELS],
|
output = np.array([self.multicolor_modes[self.effect_opts["Gradient"]["color_mode"]][0][:config.N_PIXELS],
|
||||||
self.multicolor_modes[self.effect_opts["Gradient"]["color_mode"]][1][:config.N_PIXELS],
|
self.multicolor_modes[self.effect_opts["Gradient"]["color_mode"]][1][:config.N_PIXELS],
|
||||||
self.multicolor_modes[self.effect_opts["Gradient"]["color_mode"]][2][:config.N_PIXELS]])
|
self.multicolor_modes[self.effect_opts["Gradient"]["color_mode"]][2][:config.N_PIXELS]])
|
||||||
@ -444,6 +493,7 @@ class Visualizer():
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
def visualize_fade(self, y):
|
def visualize_fade(self, y):
|
||||||
|
"Fades through a multicolour gradient, non audio reactive"
|
||||||
output = [[self.multicolor_modes[self.effect_opts["Fade"]["color_mode"]][0][0] for i in range(config.N_PIXELS)],
|
output = [[self.multicolor_modes[self.effect_opts["Fade"]["color_mode"]][0][0] for i in range(config.N_PIXELS)],
|
||||||
[self.multicolor_modes[self.effect_opts["Fade"]["color_mode"]][1][0] for i in range(config.N_PIXELS)],
|
[self.multicolor_modes[self.effect_opts["Fade"]["color_mode"]][1][0] for i in range(config.N_PIXELS)],
|
||||||
[self.multicolor_modes[self.effect_opts["Fade"]["color_mode"]][2][0] for i in range(config.N_PIXELS)]]
|
[self.multicolor_modes[self.effect_opts["Fade"]["color_mode"]][2][0] for i in range(config.N_PIXELS)]]
|
||||||
@ -757,9 +807,7 @@ def microphone_update(audio_samples):
|
|||||||
y_roll[:-1] = y_roll[1:]
|
y_roll[:-1] = y_roll[1:]
|
||||||
y_roll[-1, :] = np.copy(y)
|
y_roll[-1, :] = np.copy(y)
|
||||||
y_data = np.concatenate(y_roll, axis=0).astype(np.float32)
|
y_data = np.concatenate(y_roll, axis=0).astype(np.float32)
|
||||||
|
|
||||||
vol = np.max(np.abs(y_data))
|
vol = np.max(np.abs(y_data))
|
||||||
|
|
||||||
# Transform audio input into the frequency domain
|
# Transform audio input into the frequency domain
|
||||||
N = len(y_data)
|
N = len(y_data)
|
||||||
N_zeros = 2**int(np.ceil(np.log2(N))) - N
|
N_zeros = 2**int(np.ceil(np.log2(N))) - N
|
||||||
@ -770,9 +818,8 @@ def microphone_update(audio_samples):
|
|||||||
# Construct a Mel filterbank from the FFT data
|
# Construct a Mel filterbank from the FFT data
|
||||||
mel = np.atleast_2d(YS).T * dsp.mel_y.T
|
mel = np.atleast_2d(YS).T * dsp.mel_y.T
|
||||||
# Scale data to values more suitable for visualization
|
# Scale data to values more suitable for visualization
|
||||||
# mel = np.sum(mel, axis=0)
|
|
||||||
mel = np.sum(mel, axis=0)
|
mel = np.sum(mel, axis=0)
|
||||||
mel = mel**2.0
|
mel = mel**0.8
|
||||||
# Gain normalization
|
# Gain normalization
|
||||||
mel_gain.update(np.max(gaussian_filter1d(mel, sigma=1.0)))
|
mel_gain.update(np.max(gaussian_filter1d(mel, sigma=1.0)))
|
||||||
mel /= mel_gain.value
|
mel /= mel_gain.value
|
||||||
|
Loading…
Reference in New Issue
Block a user