Fixed effects and ws2812 controller fw

Final push to this fork unless other critical errors are found.
This commit is contained in:
Matthew Bowley 2018-03-04 20:21:34 +00:00
parent 9d84283e01
commit 48cb1018e9
4 changed files with 492 additions and 203 deletions

View File

@ -1,79 +1,131 @@
#include <Arduino.h> #include <Arduino.h>
#include <ESP8266WiFi.h> #include <ArduinoOTA.h>
//#include <WebSocketsServer.h> #include <ESP8266WiFi.h>
//#include <Hash.h> #include <WiFiUdp.h>
#include <WiFiUdp.h>
#include <NeoPixelBus.h> #define FASTLED_ESP8266_DMA // better control for ESP8266 will output or RX pin requires fork https://github.com/coryking/FastLED
#include "FastLED.h"
// Set to the number of LEDs in your LED strip
#define NUM_LEDS 242 /************ Network Information (CHANGE THESE FOR YOUR SETUP) ************************/
// Maximum number of packets to hold in the buffer. Don't change this. const char* ssid = "WIFI_SSID";
#define BUFFER_LEN 726 const char* password = "WIFI_PASSWORD";
// Toggles FPS output (1 = print FPS over serial, 0 = disable output)
#define PRINT_FPS 1 const char* sensor_name = "TEST_SENSOR_HOSTNAME";
const char* ota_password = "OTA_PASSWORD";
//NeoPixelBus settings
const uint8_t PixelPin = 3; // make sure to set this to the correct pin, ignored for Esp8266(set to 3 by default for DMA) const bool static_ip = true;
IPAddress ip(192, 168, 1, 112);
// Wifi and socket settings IPAddress gateway(192, 168, 1, 1);
const char* ssid = "YOUR_WIFI_SSID"; IPAddress subnet(255, 255, 255, 0);
const char* password = "YOUR_WIFI_PASSWORD";
unsigned int localPort = 7778; const int udp_port = 7778;
byte packetBuffer[BUFFER_LEN];
RgbColor ledDataBuffer[NUM_LEDS]; /*********************************** FastLED Defintions ********************************/
#define NUM_LEDS 250
// LED strip #define DATA_PIN 5
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> ledstrip(NUM_LEDS, PixelPin); //#define CLOCK_PIN 2
#define CHIPSET WS2812B
WiFiUDP port; #define COLOR_ORDER GRB
// Network information /*********************************** Globals *******************************************/
// IP must match the IP in config.py WiFiUDP port;
IPAddress ip(192, 168, 137, 200); CRGB leds[NUM_LEDS];
// Set gateway to your router's gateway
IPAddress gateway(192, 168, 137, 1); /********************************** Start Setup ****************************************/
IPAddress subnet(255, 255, 255, 0); void setup() {
Serial.begin(115200);
void setup() {
Serial.begin(115200); // Setup FastLED
//WiFi.config(ip, gateway, subnet); #ifdef CLOCK_PIN
WiFi.mode(WIFI_STA); FastLED.addLeds<CHIPSET, DATA_PIN, CLOCK_PIN, COLOR_ORDER>(leds, NUM_LEDS);
WiFi.begin(ssid, password); #else
Serial.println(""); FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
// Connect to wifi and print the IP address over serial #endif
while (WiFi.status() != WL_CONNECTED) {
delay(500); // Setup the wifi connection
Serial.print("."); setup_wifi();
}
Serial.println(""); // Setup OTA firmware updates
Serial.print("Connected to "); setup_ota();
Serial.println(ssid);
Serial.print("IP address: "); // Initialize the UDP port
Serial.println(WiFi.localIP()); port.begin(udp_port);
port.begin(localPort); }
ledstrip.Begin();//Begin output
ledstrip.Show();//Clear the strip for use void setup_wifi() {
} delay(10);
uint8_t N = 0; Serial.println();
#if PRINT_FPS Serial.print("Connecting to ");
uint16_t fpsCounter = 0; Serial.print(ssid);
uint32_t secondTimer = 0;
#endif if (static_ip) {
WiFi.config(ip, gateway, subnet);
void loop() { }
// Read data over socket
int packetSize = port.parsePacket(); WiFi.hostname(sensor_name);
// If packets have been received, interpret the command WiFi.mode(WIFI_STA);
if (packetSize) { WiFi.begin(ssid, password);
int len = port.read(packetBuffer, BUFFER_LEN);
for(int i = 0; i < len; i+=4) { while (WiFi.status() != WL_CONNECTED) {
packetBuffer[len] = 0; delay(500);
N = packetBuffer[i]; Serial.print(".");
RgbColor pixel((uint8_t)packetBuffer[i+1], (uint8_t)packetBuffer[i+2], (uint8_t)packetBuffer[i+3]); }
ledstrip.SetPixelColor(N, pixel);
} Serial.println("");
ledstrip.Show(); Serial.println("WiFi connected!");
Serial.print("/"); Serial.print("IP address: ");
} Serial.println(WiFi.localIP());
} }
void setup_ota() {
ArduinoOTA.setHostname(sensor_name);
ArduinoOTA.setPassword(ota_password);
ArduinoOTA.onStart([]() {
Serial.println("Starting");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
delay(1);
Serial.print("WIFI Disconnected. Attempting reconnection.");
setup_wifi();
return;
}
ArduinoOTA.handle();
// TODO: Hookup either a more elaborate protocol, or a secondary
// communication channel (i.e. mqtt) for functional control. This
// will also give the ability to have some non-reative effects to
// be driven completely locally making them less glitchy.
// Handle UDP data
int packetSize = port.parsePacket();
if (packetSize == sizeof(leds)) {
port.read((char*)leds, sizeof(leds));
FastLED.show();
} else if (packetSize) {
Serial.printf("Invalid packet size: %u (expected %u)\n", packetSize, sizeof(leds));
port.flush();
return;
}
}

View File

@ -20,7 +20,7 @@ settings = { # All settings
'MAX_FREQUENCY': 18000, # Frequencies above this value will be removed during audio processing 'MAX_FREQUENCY': 18000, # Frequencies above this value will be removed during audio processing
'MAX_BRIGHTNESS': 250, # Frequencies above this value will be removed during audio processing 'MAX_BRIGHTNESS': 250, # Frequencies above this value will be removed during audio processing
'N_ROLLING_HISTORY': 4, # Number of past audio frames to include in the rolling window 'N_ROLLING_HISTORY': 4, # Number of past audio frames to include in the rolling window
'MIN_VOLUME_THRESHOLD': 0.01 # No music visualization displayed if recorded audio volume below threshold 'MIN_VOLUME_THRESHOLD': 0.001 # No music visualization displayed if recorded audio volume below threshold
#'LOGARITHMIC_SCALING': True, # Scale frequencies logarithmically to match perceived pitch of human ear #'LOGARITHMIC_SCALING': True, # Scale frequencies logarithmically to match perceived pitch of human ear
}, },
@ -32,7 +32,7 @@ settings = { # All settings
# All devices and their respective settings. Indexed by name, call each one what you want. # All devices and their respective settings. Indexed by name, call each one what you want.
"devices":{"Desk Strip":{ "devices":{"Desk Strip":{
"configuration":{"TYPE": "esp8266", # Device type (see below for all supported boards) "configuration":{"TYPE": "ESP8266", # Device type (see below for all supported boards)
# Required configuration for device. See below for all required keys per device # Required configuration for device. See below for all required keys per device
"AUTO_DETECT": True, # Set this true if you're using windows hotspot to connect (see below for more info) "AUTO_DETECT": True, # Set this true if you're using windows hotspot to connect (see below for more info)
"MAC_ADDR": "2c-3a-e8-2f-2c-9f", # MAC address of the ESP8266. Only used if AUTO_DETECT is True "MAC_ADDR": "2c-3a-e8-2f-2c-9f", # MAC address of the ESP8266. Only used if AUTO_DETECT is True
@ -42,7 +42,7 @@ settings = { # All settings
# Other configuration # Other configuration
"N_PIXELS": 58, # Number of pixels in the LED strip (must match ESP8266 firmware) "N_PIXELS": 58, # Number of pixels in the LED strip (must match ESP8266 firmware)
"N_FFT_BINS": 24, # Number of frequency bins to use when transforming audio to frequency domain "N_FFT_BINS": 24, # Number of frequency bins to use when transforming audio to frequency domain
"current_effect": "Single" # Currently selected effect for this board, used as default when program launches "current_effect": "Energy" # Currently selected effect for this board, used as default when program launches
}, },
# Configurable options for this board's effects go in this dictionary. # Configurable options for this board's effects go in this dictionary.
@ -67,7 +67,10 @@ settings = { # All settings
"reverse_roll": False, # Reverse movement of gradient roll "reverse_roll": False, # Reverse movement of gradient roll
"blur": 3.0, # Amount of blur to apply "blur": 3.0, # Amount of blur to apply
"flip_lr":False}, # Flip output left-right "flip_lr":False}, # Flip output left-right
"Scroll": {"decay": 0.995, # How quickly the colour fades away as it moves "Scroll": {"lows_color": "Red", # Colour of low frequencies
"mids_color": "Green", # Colour of mid frequencies
"high_color": "Blue", # Colour of high frequencies
"decay": 0.995, # How quickly the colour fades away as it moves
"speed": 1, # Speed of scroll "speed": 1, # Speed of scroll
"r_multiplier": 1.0, # How much red "r_multiplier": 1.0, # How much red
"g_multiplier": 1.0, # How much green "g_multiplier": 1.0, # How much green
@ -101,7 +104,7 @@ settings = { # All settings
} }
}, },
"Main Strip":{ "Main Strip":{
"configuration":{"TYPE": "esp8266", # Device type (see below for all supported boards) "configuration":{"TYPE": "ESP8266", # Device type (see below for all supported boards)
# Required configuration for device. See below for all required keys per device # Required configuration for device. See below for all required keys per device
"AUTO_DETECT": True, # Set this true if you're using windows hotspot to connect (see below for more info) "AUTO_DETECT": True, # Set this true if you're using windows hotspot to connect (see below for more info)
"MAC_ADDR": "5c-cf-7f-f0-8c-f3", # MAC address of the ESP8266. Only used if AUTO_DETECT is True "MAC_ADDR": "5c-cf-7f-f0-8c-f3", # MAC address of the ESP8266. Only used if AUTO_DETECT is True
@ -136,7 +139,10 @@ settings = { # All settings
"reverse_roll": False, # Reverse movement of gradient roll "reverse_roll": False, # Reverse movement of gradient roll
"blur": 3.0, # Amount of blur to apply "blur": 3.0, # Amount of blur to apply
"flip_lr":False}, # Flip output left-right "flip_lr":False}, # Flip output left-right
"Scroll": {"decay": 0.995, # How quickly the colour fades away as it moves "Scroll": {"lows_color": "Red", # Colour of low frequencies
"mids_color": "Green", # Colour of mid frequencies
"high_color": "Blue", # Colour of high frequencies
"decay": 0.995, # How quickly the colour fades away as it moves
"speed": 1, # Speed of scroll "speed": 1, # Speed of scroll
"r_multiplier": 1.0, # How much red "r_multiplier": 1.0, # How much red
"g_multiplier": 1.0, # How much green "g_multiplier": 1.0, # How much green
@ -190,11 +196,56 @@ settings = { # All settings
"Sunset" : ["Red", "Orange", "Yellow"], "Sunset" : ["Red", "Orange", "Yellow"],
"Ocean" : ["Green", "Light blue", "Blue"], "Ocean" : ["Green", "Light blue", "Blue"],
"Jungle" : ["Green", "Red", "Orange"], "Jungle" : ["Green", "Red", "Orange"],
"Sunny" : ["Yellow", "Light blue", "Orange", "Blue"] "Sunny" : ["Yellow", "Light blue", "Orange", "Blue"],
"Fruity" : ["Orange", "Blue"],
"Peach" : ["Orange", "Pink"],
"Rust" : ["Orange", "Red"]
} }
} }
device_req_config = {"Stripless" : None, # duh
"BlinkStick" : None,
"DotStar" : None,
"ESP8266" : {"AUTO_DETECT": ["Auto Detect",
"Automatically detect device on network using MAC address",
"checkbox",
True],
"MAC_ADDR" : ["Mac Address",
"Hardware address of device, used for auto-detection",
"textbox",
"aa-bb-cc-dd-ee-ff"],
"UDP_IP" : ["IP Address",
"IP address of device, used if auto-detection isn't active",
"textbox",
"xxx.xxx.xxx.xxx"],
"UDP_PORT" : ["Port",
"Port used to communicate with device",
"textbox",
"7778"]},
"RaspberryPi" : {"LED_PIN" : ["LED Pin",
"GPIO pin connected to the LED strip RaspberryPi (must support PWM)",
"textbox",
"10"],
"LED_FREQ_HZ": ["LED Frequency",
"LED signal frequency in Hz",
"textbox",
"800000"],
"LED_DMA" : ["DMA Channel",
"DMA channel used for generating PWM signal",
"textbox",
"5"],
"LED_INVERT" : ["Invert LEDs",
"Set True if using an inverting logic level converter",
"checkbox",
True]},
"Fadecandy" : {"SERVER" : ["Server Address",
"Address of Fadecandy server",
"textbox",
"localhost:7890"]}
}
""" """
~~ NOTES ~~ ~~ NOTES ~~
@ -215,45 +266,45 @@ be loaded. Basically it works as you would expect it to.
Device used to control LED strip. Device used to control LED strip.
'esp8266' means that you are using an ESP8266 module to control the LED strip 'ESP8266' means that you are using an ESP8266 module to control the LED strip
and commands will be sent to the ESP8266 over WiFi. You can have as many of and commands will be sent to the ESP8266 over WiFi. You can have as many of
these as your computer is able to handle. these as your computer is able to handle.
'pi' means that you are using a Raspberry Pi as a standalone unit to process 'RaspberryPi' means that you are using a Raspberry Pi as a standalone unit to process
audio input and control the LED strip directly. audio input and control the LED strip directly.
'blinkstick' means that a BlinkstickPro is connected to this PC which will be used 'BlinkStick' means that a BlinkstickPro is connected to this PC which will be used
to control the leds connected to it. to control the leds connected to it.
'fadecandy' means that a fadecandy server is running on your computer and is connected 'Fadecandy' means that a Fadecandy server is running on your computer and is connected
via usb to a fadecandy board connected to LEDs via usb to a Fadecandy board connected to LEDs
'dotstar' creates an APA102-based output device. LMK if you have any success 'DotStar' creates an APA102-based output device. LMK if you have any success
getting this to work becuase i have no clue if it will. getting this to work becuase i have no clue if it will.
'stripless' means that the program will run without sending data to a strip. 'Stripless' means that the program will run without sending data to a strip.
Useful for development etc, but doesn't look half as good ;) Useful for development etc, but doesn't look half as good ;)
[REQUIRED CONFIGURATION KEYS] [REQUIRED CONFIGURATION KEYS]
===== 'esp8266' ===== 'ESP8266'
"AUTO_DETECT" # Set this true if you're using windows hotspot to connect (see below for more info) "AUTO_DETECT" # Set this true if you're using windows hotspot to connect (see below for more info)
"MAC_ADDR" # MAC address of the ESP8266. Only used if AUTO_DETECT is True "MAC_ADDR" # MAC address of the ESP8266. Only used if AUTO_DETECT is True
"UDP_IP" # IP address of the ESP8266. Must match IP in ws2812_controller.ino "UDP_IP" # IP address of the ESP8266. Must match IP in ws2812_controller.ino
"UDP_PORT" # Port number used for socket communication between Python and ESP8266 "UDP_PORT" # Port number used for socket communication between Python and ESP8266
===== 'pi' ===== 'RaspberryPi'
"LED_PIN" # GPIO pin connected to the LED strip pixels (must support PWM) "LED_PIN" # GPIO pin connected to the LED strip pixels (must support PWM)
"LED_FREQ_HZ" # LED signal frequency in Hz (usually 800kHz) "LED_FREQ_HZ" # LED signal frequency in Hz (usually 800kHz)
"LED_DMA" # DMA channel used for generating PWM signal (try 5) "LED_DMA" # DMA channel used for generating PWM signal (try 5)
"BRIGHTNESS" # Brightness of LED strip between 0 and 255 "BRIGHTNESS" # Brightness of LED strip between 0 and 255
"LED_INVERT" # Set True if using an inverting logic level converter "LED_INVERT" # Set True if using an inverting logic level converter
===== 'blinkstick' ===== 'BlinkStick'
No required configuration keys No required configuration keys
===== 'fadecandy' ===== 'Fadecandy'
"SERVER" # Address of fadecandy server. (usually 'localhost:7890') "SERVER" # Address of Fadecandy server. (usually 'localhost:7890')
===== 'dotstar' ===== 'DotStar'
No required configuration keys No required configuration keys
===== 'stripless' ===== 'Stripless'
No required configuration keys (heh) No required configuration keys (heh)
[AUTO_DETECT] [AUTO_DETECT]
@ -293,19 +344,19 @@ There is no point using more bins than there are pixels on the LED strip.
""" """
for board in settings["devices"]: for board in settings["devices"]:
if settings["devices"][board]["configuration"]["TYPE"] == 'esp8266': if settings["devices"][board]["configuration"]["TYPE"] == 'ESP8266':
settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False
# Set to False because the firmware handles gamma correction + dither # Set to False because the firmware handles gamma correction + dither
elif settings["devices"][board]["configuration"]["TYPE"] == 'pi': elif settings["devices"][board]["configuration"]["TYPE"] == 'RaspberryPi':
settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = True settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = True
# Set to True because Raspberry Pi doesn't use hardware dithering # Set to True because Raspberry Pi doesn't use hardware dithering
elif settings["devices"][board]["configuration"]["TYPE"] == 'blinkstick': elif settings["devices"][board]["configuration"]["TYPE"] == 'BlinkStick':
settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = True settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = True
elif settings["devices"][board]["configuration"]["TYPE"] == 'dotstar': elif settings["devices"][board]["configuration"]["TYPE"] == 'DotStar':
settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False
elif settings["devices"][board]["configuration"]["TYPE"] == 'fadecandy': elif settings["devices"][board]["configuration"]["TYPE"] == 'Fadecandy':
settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False
elif settings["devices"][board]["configuration"]["TYPE"] == 'stripless': elif settings["devices"][board]["configuration"]["TYPE"] == 'Stripless':
settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False settings["devices"][board]["configuration"]["SOFTWARE_GAMMA_CORRECTION"] = False
else: else:
raise ValueError("Invalid device selected. Device {} not known.".format(settings["devices"][board]["configuration"]["TYPE"])) raise ValueError("Invalid device selected. Device {} not known.".format(settings["devices"][board]["configuration"]["TYPE"]))

6
python/lib/settings.ini Normal file

File diff suppressed because one or more lines are too long

View File

@ -47,7 +47,8 @@ class Visualizer():
self.beat_count = 0 self.beat_count = 0
self.freq_channels = [deque(maxlen=self.freq_channel_history) for i in range(config.settings["devices"][self.board]["configuration"]["N_FFT_BINS"])] self.freq_channels = [deque(maxlen=self.freq_channel_history) for i in range(config.settings["devices"][self.board]["configuration"]["N_FFT_BINS"])]
self.prev_output = np.array([[0 for i in range(config.settings["devices"][self.board]["configuration"]["N_PIXELS"])] for i in range(3)]) self.prev_output = np.array([[0 for i in range(config.settings["devices"][self.board]["configuration"]["N_PIXELS"])] for i in range(3)])
self.prev_spectrum = [0 for i in range(config.settings["devices"][self.board]["configuration"]["N_PIXELS"]//2)] self.output = np.array([[0 for i in range(config.settings["devices"][self.board]["configuration"]["N_PIXELS"])] for i in range(3)])
self.prev_spectrum = np.array([config.settings["devices"][self.board]["configuration"]["N_PIXELS"] // 2])
self.current_freq_detects = {"beat":False, self.current_freq_detects = {"beat":False,
"low":False, "low":False,
"mid":False, "mid":False,
@ -118,12 +119,12 @@ class Visualizer():
["reverse_grad", "Reverse Gradient", "checkbox"], ["reverse_grad", "Reverse Gradient", "checkbox"],
["reverse_roll", "Reverse Roll", "checkbox"], ["reverse_roll", "Reverse Roll", "checkbox"],
["flip_lr", "Flip LR", "checkbox"]], ["flip_lr", "Flip LR", "checkbox"]],
"Scroll":[["blur", "Blur", "float_slider", (0.05,4.0,0.05)], "Scroll":[["lows_color", "Lows Color", "dropdown", config.settings["colors"]],
["mids_color", "Mids Color", "dropdown", config.settings["colors"]],
["high_color", "Highs Color", "dropdown", config.settings["colors"]],
["blur", "Blur", "float_slider", (0.05,4.0,0.05)],
["decay", "Decay", "float_slider", (0.97,1.0,0.0005)], ["decay", "Decay", "float_slider", (0.97,1.0,0.0005)],
["speed", "Speed", "slider", (1,5,1)], ["speed", "Speed", "slider", (1,5,1)]],
["r_multiplier", "Red", "float_slider", (0.05,1.0,0.05)],
["g_multiplier", "Green", "float_slider", (0.05,1.0,0.05)],
["b_multiplier", "Blue", "float_slider", (0.05,1.0,0.05)]],
"Power":[["color_mode", "Color Mode", "dropdown", config.settings["gradients"]], "Power":[["color_mode", "Color Mode", "dropdown", config.settings["gradients"]],
["s_color", "Spark Color ", "dropdown", config.settings["colors"]], ["s_color", "Spark Color ", "dropdown", config.settings["colors"]],
["s_count", "Spark Amount", "slider", (0,config.settings["devices"][self.board]["configuration"]["N_PIXELS"]//6,1)], ["s_count", "Spark Amount", "slider", (0,config.settings["devices"][self.board]["configuration"]["N_PIXELS"]//6,1)],
@ -149,8 +150,9 @@ class Visualizer():
["g", "Green value", "slider", (0,255,1)], ["g", "Green value", "slider", (0,255,1)],
["b", "Blue value", "slider", (0,255,1)]] ["b", "Blue value", "slider", (0,255,1)]]
} }
# Setup for latency timer # Setup for fps counter
self.latency_deque = deque(maxlen=1000) self.frame_counter = 0
self.start_time = time.time()
# Setup for "Wave" (don't change these) # Setup for "Wave" (don't change these)
self.wave_wipe_count = 0 self.wave_wipe_count = 0
# Setup for "Power" (don't change these) # Setup for "Power" (don't change these)
@ -270,17 +272,23 @@ class Visualizer():
def get_vis(self, y, audio_input): def get_vis(self, y, audio_input):
self.update_freq_channels(y) self.update_freq_channels(y)
self.detect_freqs() self.detect_freqs()
time1 = time.time()
if config.settings["devices"][self.board]["configuration"]["current_effect"] in self.non_reactive_effects: if config.settings["devices"][self.board]["configuration"]["current_effect"] in self.non_reactive_effects:
self.prev_output = self.effects[config.settings["devices"][self.board]["configuration"]["current_effect"]]() self.prev_output = self.effects[config.settings["devices"][self.board]["configuration"]["current_effect"]]()
elif audio_input: elif audio_input:
self.prev_output = self.effects[config.settings["devices"][self.board]["configuration"]["current_effect"]](y) self.prev_output = self.effects[config.settings["devices"][self.board]["configuration"]["current_effect"]](y)
else: else:
self.prev_output = np.multiply(self.prev_output, 0.95) self.prev_output = np.multiply(self.prev_output, 0.95)
time2 = time.time() self.frame_counter += 1
self.latency_deque.append(1000*(time2-time1)) elapsed = time.time() - self.start_time
if config.settings["configuration"]["USE_GUI"]: if elapsed >= 1.0:
gui.label_latency.setText("{} ms Processing Latency ".format(int(sum(self.latency_deque)/len(self.latency_deque)))) self.start_time = time.time()
fps = self.frame_counter//elapsed
latency = elapsed/self.frame_counter
self.frame_counter = 0
if config.settings["configuration"]["USE_GUI"]:
gui.label_latency.setText("{:0.3f} ms Processing Latency ".format(latency))
gui.label_fps.setText('{:.0f} / {:.0f} FPS '.format(fps, config.settings["configuration"]["FPS"]))
return self.prev_output return self.prev_output
def _split_equal(self, value, parts): def _split_equal(self, value, parts):
@ -315,54 +323,76 @@ class Visualizer():
def visualize_scroll(self, y): def visualize_scroll(self, y):
"""Effect that originates in the center and scrolls outwards""" """Effect that originates in the center and scrolls outwards"""
global p
y = y**4.0 y = y**4.0
signal_processers[self.board].gain.update(y) # signal_processers[self.board].gain.update(y)
y /= signal_processers[self.board].gain.value # y /= signal_processers[self.board].gain.value
y *= 255.0 # y *= 255.0
r = int(np.max(y[:len(y) // 3])*config.settings["devices"][self.board]["effect_opts"]["Scroll"]["r_multiplier"]) n_pixels = config.settings["devices"][self.board]["configuration"]["N_PIXELS"]
g = int(np.max(y[len(y) // 3: 2 * len(y) // 3])*config.settings["devices"][self.board]["effect_opts"]["Scroll"]["g_multiplier"]) y = np.copy(interpolate(y, n_pixels // 2))
b = int(np.max(y[2 * len(y) // 3:])*config.settings["devices"][self.board]["effect_opts"]["Scroll"]["b_multiplier"]) signal_processers[self.board].common_mode.update(y)
diff = y - self.prev_spectrum
self.prev_spectrum = np.copy(y)
# split spectrum up
# r = signal_processers[self.board].r_filt.update(y - signal_processers[self.board].common_mode.value)
# g = np.abs(diff)
# b = signal_processers[self.board].b_filt.update(np.copy(y))
y = np.clip(y, 0, 1)
lows = y[:len(y) // 6]
mids = y[len(y) // 6: 2 * len(y) // 5]
high = y[2 * len(y) // 5:]
# max values
lows_max = np.max(lows)#*config.settings["devices"][self.board]["effect_opts"]["Scroll"]["lows_multiplier"])
mids_max = float(np.max(mids))#*config.settings["devices"][self.board]["effect_opts"]["Scroll"]["mids_multiplier"])
high_max = float(np.max(high))#*config.settings["devices"][self.board]["effect_opts"]["Scroll"]["high_multiplier"])
# indexes of max values
# map to colour gradient
lows_val = (np.array(config.settings["colors"][config.settings["devices"][self.board]["effect_opts"]["Scroll"]["lows_color"]]) * lows_max).astype(int)
mids_val = (np.array(config.settings["colors"][config.settings["devices"][self.board]["effect_opts"]["Scroll"]["mids_color"]]) * mids_max).astype(int)
high_val = (np.array(config.settings["colors"][config.settings["devices"][self.board]["effect_opts"]["Scroll"]["high_color"]]) * high_max).astype(int)
# Scrolling effect window # Scrolling effect window
speed = config.settings["devices"][self.board]["effect_opts"]["Scroll"]["speed"] speed = config.settings["devices"][self.board]["effect_opts"]["Scroll"]["speed"]
p[:, speed:] = p[:, :-speed] self.output[:, speed:] = self.output[:, :-speed]
p *= config.settings["devices"][self.board]["effect_opts"]["Scroll"]["decay"] self.output = (self.output * config.settings["devices"][self.board]["effect_opts"]["Scroll"]["decay"]).astype(int)
p = gaussian_filter1d(p, sigma=config.settings["devices"][self.board]["effect_opts"]["Scroll"]["blur"]) self.output = gaussian_filter1d(self.output, sigma=config.settings["devices"][self.board]["effect_opts"]["Scroll"]["blur"])
# Create new color originating at the center # Create new color originating at the center
p[0, :speed] = r self.output[0, :speed] = lows_val[0] + mids_val[0] + high_val[0]
p[1, :speed] = g self.output[1, :speed] = lows_val[1] + mids_val[1] + high_val[1]
p[2, :speed] = b self.output[2, :speed] = lows_val[2] + mids_val[2] + high_val[2]
# Update the LED strip # Update the LED strip
return np.concatenate((p[:, ::-1], p), axis=1) #return np.concatenate((self.prev_spectrum[:, ::-speed], self.prev_spectrum), axis=1)
return self.output
def visualize_energy(self, y): def visualize_energy(self, y):
"""Effect that expands from the center with increasing sound energy""" """Effect that expands from the center with increasing sound energy"""
global p
y = np.copy(y) y = np.copy(y)
signal_processers[self.board].gain.update(y) signal_processers[self.board].gain.update(y)
y /= signal_processers[self.board].gain.value y /= signal_processers[self.board].gain.value
scale = config.settings["devices"][self.board]["effect_opts"]["Energy"]["scale"] scale = config.settings["devices"][self.board]["effect_opts"]["Energy"]["scale"]
# Scale by the width of the LED strip # Scale by the width of the LED strip
y *= float((config.settings["devices"][self.board]["configuration"]["N_PIXELS"] * scale) - 1) y *= float((config.settings["devices"][self.board]["configuration"]["N_PIXELS"] * scale) - 1)
y = np.copy(interpolate(y, config.settings["devices"][self.board]["configuration"]["N_PIXELS"] // 2))
# Map color channels according to energy in the different freq bands # Map color channels according to energy in the different freq bands
r = int(np.mean(y[:len(y) // 3]**scale)*config.settings["devices"][self.board]["effect_opts"]["Energy"]["r_multiplier"]) #y = np.copy(interpolate(y, config.settings["devices"][self.board]["configuration"]["N_PIXELS"] // 2))
g = int(np.mean(y[len(y) // 3: 2 * len(y) // 3]**scale)*config.settings["devices"][self.board]["effect_opts"]["Energy"]["g_multiplier"]) diff = y - self.prev_spectrum
b = int(np.mean(y[2 * len(y) // 3:]**scale)*config.settings["devices"][self.board]["effect_opts"]["Energy"]["b_multiplier"]) self.prev_spectrum = np.copy(y)
spectrum = np.copy(self.prev_spectrum)
spectrum = np.array([j for i in zip(spectrum,spectrum) for j in i])
# Color channel mappings
r = int(np.mean(spectrum[:len(spectrum) // 3]**scale)*config.settings["devices"][self.board]["effect_opts"]["Energy"]["r_multiplier"])
g = int(np.mean(spectrum[len(spectrum) // 3: 2 * len(spectrum) // 3]**scale)*config.settings["devices"][self.board]["effect_opts"]["Energy"]["g_multiplier"])
b = int(np.mean(spectrum[2 * len(spectrum) // 3:]**scale)*config.settings["devices"][self.board]["effect_opts"]["Energy"]["b_multiplier"])
# Assign color to different frequency regions # Assign color to different frequency regions
p[0, :r] = 255.0 self.output[0, :r] = 255
p[0, r:] = 0.0 self.output[0, r:] = 0
p[1, :g] = 255.0 self.output[1, :g] = 255
p[1, g:] = 0.0 self.output[1, g:] = 0
p[2, :b] = 255.0 self.output[2, :b] = 255
p[2, b:] = 0.0 self.output[2, b:] = 0
signal_processers[self.board].p_filt.update(p)
p = np.round(signal_processers[self.board].p_filt.value)
# Apply blur to smooth the edges # Apply blur to smooth the edges
p[0, :] = gaussian_filter1d(p[0, :], sigma=config.settings["devices"][self.board]["effect_opts"]["Energy"]["blur"]) self.output[0, :] = gaussian_filter1d(self.output[0, :], sigma=config.settings["devices"][self.board]["effect_opts"]["Energy"]["blur"])
p[1, :] = gaussian_filter1d(p[1, :], sigma=config.settings["devices"][self.board]["effect_opts"]["Energy"]["blur"]) self.output[1, :] = gaussian_filter1d(self.output[1, :], sigma=config.settings["devices"][self.board]["effect_opts"]["Energy"]["blur"])
p[2, :] = gaussian_filter1d(p[2, :], sigma=config.settings["devices"][self.board]["effect_opts"]["Energy"]["blur"]) self.output[2, :] = gaussian_filter1d(self.output[2, :], sigma=config.settings["devices"][self.board]["effect_opts"]["Energy"]["blur"])
# Set the new pixel value return self.output
return np.concatenate((p[:, ::-1], p), axis=1)
def visualize_wavelength(self, y): def visualize_wavelength(self, y):
y = np.copy(interpolate(y, config.settings["devices"][self.board]["configuration"]["N_PIXELS"] // 2)) y = np.copy(interpolate(y, config.settings["devices"][self.board]["configuration"]["N_PIXELS"] // 2))
@ -371,7 +401,7 @@ class Visualizer():
self.prev_spectrum = np.copy(y) self.prev_spectrum = np.copy(y)
# Color channel mappings # Color channel mappings
r = signal_processers[self.board].r_filt.update(y - signal_processers[self.board].common_mode.value) r = signal_processers[self.board].r_filt.update(y - signal_processers[self.board].common_mode.value)
#g = np.abs(diff) g = np.abs(diff)
b = signal_processers[self.board].b_filt.update(np.copy(y)) b = signal_processers[self.board].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])
output = np.array([self.multicolor_modes[config.settings["devices"][self.board]["effect_opts"]["Wavelength"]["color_mode"]][0][ output = np.array([self.multicolor_modes[config.settings["devices"][self.board]["effect_opts"]["Wavelength"]["color_mode"]][0][
@ -399,7 +429,6 @@ class Visualizer():
def visualize_spectrum(self, y): def visualize_spectrum(self, y):
"""Effect that maps the Mel filterbank frequencies onto the LED strip""" """Effect that maps the Mel filterbank frequencies onto the LED strip"""
global p
#print(len(y)) #print(len(y))
#print(y) #print(y)
y = np.copy(interpolate(y, config.settings["devices"][self.board]["configuration"]["N_PIXELS"] // 2)) y = np.copy(interpolate(y, config.settings["devices"][self.board]["configuration"]["N_PIXELS"] // 2))
@ -541,7 +570,7 @@ class Visualizer():
return output return output
def visualize_pulse(self, y): def visualize_pulse(self, y):
"""fckin dope ass visuals that's what""" """dope ass visuals that's what"""
config.settings["devices"][self.board]["effect_opts"]["Pulse"]["bar_color"] config.settings["devices"][self.board]["effect_opts"]["Pulse"]["bar_color"]
config.settings["devices"][self.board]["effect_opts"]["Pulse"]["bar_speed"] config.settings["devices"][self.board]["effect_opts"]["Pulse"]["bar_speed"]
config.settings["devices"][self.board]["effect_opts"]["Pulse"]["bar_length"] config.settings["devices"][self.board]["effect_opts"]["Pulse"]["bar_length"]
@ -602,7 +631,7 @@ class GUI(QMainWindow):
self.updateUIVisibleItems() self.updateUIVisibleItems()
def initMainWindow(self): def initMainWindow(self):
# ==================================== Set up window and wrapping layout # Set up window and wrapping layout
self.setWindowTitle("Visualization") self.setWindowTitle("Visualization")
# Initial window size/pos last saved if available # Initial window size/pos last saved if available
settings.beginGroup("MainWindow") settings.beginGroup("MainWindow")
@ -613,19 +642,22 @@ class GUI(QMainWindow):
settings.endGroup() settings.endGroup()
self.main_wrapper = QVBoxLayout() self.main_wrapper = QVBoxLayout()
# ======================================================= Set up toolbar # Set up toolbar
#toolbar_guiDialogue.setShortcut('Ctrl+H') #toolbar_guiDialogue.setShortcut('Ctrl+H')
toolbar_deviceDialogue = QAction('LED Strip Manager', self)
toolbar_deviceDialogue.triggered.connect(self.deviceDialogue)
toolbar_guiDialogue = QAction('GUI Properties', self) toolbar_guiDialogue = QAction('GUI Properties', self)
toolbar_guiDialogue.triggered.connect(self.guiDialogue) toolbar_guiDialogue.triggered.connect(self.guiDialogue)
#toolbar_configDialogue = QAction('GUI Properties', self) toolbar_saveDialogue = QAction('Save Settings', self)
#toolbar_configDialogue.triggered.connect(self.configDialogue) toolbar_saveDialogue.triggered.connect(self.saveDialogue)
self.toolbar = self.addToolBar('top_toolbar') self.toolbar = self.addToolBar('top_toolbar')
self.toolbar.setObjectName('top_toolbar') self.toolbar.setObjectName('top_toolbar')
self.toolbar.addAction(toolbar_guiDialogue) self.toolbar.addAction(toolbar_guiDialogue)
# self.toolbar.addAction(toolbar_configDialogue) self.toolbar.addAction(toolbar_saveDialogue)
self.toolbar.addAction(toolbar_deviceDialogue)
# ========================================== Set up FPS and error labels # Set up FPS and error labels
self.statusbar = QStatusBar() self.statusbar = QStatusBar()
self.setStatusBar(self.statusbar) self.setStatusBar(self.statusbar)
self.label_error = QLabel("") self.label_error = QLabel("")
@ -637,8 +669,8 @@ class GUI(QMainWindow):
self.statusbar.addPermanentWidget(self.label_latency) self.statusbar.addPermanentWidget(self.label_latency)
self.statusbar.addPermanentWidget(self.label_fps) self.statusbar.addPermanentWidget(self.label_fps)
# ==================================================== Set up board tabs # Set up board tabs
self.label_boards = QLabel("Boards") self.label_boards = QLabel("LED Strips")
self.boardsTabWidget = QTabWidget() self.boardsTabWidget = QTabWidget()
# Dynamically set up boards tabs # Dynamically set up boards tabs
self.board_tabs = {} # contains all the tabs for each board self.board_tabs = {} # contains all the tabs for each board
@ -648,9 +680,9 @@ class GUI(QMainWindow):
self.addBoard(board) self.addBoard(board)
self.main_wrapper.addWidget(self.label_boards) self.main_wrapper.addWidget(self.label_boards)
self.main_wrapper.addWidget(self.boardsTabWidget) self.main_wrapper.addWidget(self.boardsTabWidget)
self.setLayout(self.main_wrapper) #self.setLayout(self.main_wrapper)
# =========================================== Set wrapper as main widget # Set wrapper as main widget
self.setCentralWidget(QWidget(self)) self.setCentralWidget(QWidget(self))
self.centralWidget().setLayout(self.main_wrapper) self.centralWidget().setLayout(self.main_wrapper)
self.show() self.show()
@ -686,10 +718,185 @@ class GUI(QMainWindow):
event.ignore() event.ignore()
def updateUIVisibleItems(self): def updateUIVisibleItems(self):
#print("-UPDATE-")
for section in self.gui_widgets: for section in self.gui_widgets:
for widget in self.gui_widgets[section]: for widget in self.gui_widgets[section]:
#print(widget.isVisible(), " ", config.settings["GUI_opts"][section])
widget.setVisible(config.settings["GUI_opts"][section]) widget.setVisible(config.settings["GUI_opts"][section])
def deviceDialogue(self):
def show_hide_addBoard_interface():
current_device = device_type_cbox.currentText()
for device in config.device_req_config:
for req_config_setting in widgets[device]:
if req_config_setting is not "no_config":
for widget in widgets[device][req_config_setting]:
widget.setVisible(device == current_device)
else:
# doesn't make sense i know i know
widgets[device][req_config_setting].setVisible(device == current_device)
def validate_input():
import re
current_device = device_type_cbox.currentText()
tests = []
print("testing")
if current_device == "ESP8266":
for req_config_setting in config.device_req_config[current_device]:
test = widgets[current_device][req_config_setting][1].text()
if req_config_setting == "MAC_ADDR":
# Validate MAC
tests.append(True if re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", test.lower()) else False)
elif req_config_setting == "UDP_IP":
# Validate IP
try:
pieces = test.split('.')
if len(pieces) != 4: return False
tests.append(all(0<=int(self.prev_output)<256 for self.prev_output in pieces))
except:
tests.append(False)
elif req_config_setting == "UDP_PORT":
# Validate port
print(test)
try:
int(test)
if test > 0:
test.append(True)
except:
tests.append(False)
#pass
# Validate port
elif current_device == "RaspberryPi":
pass
# Validate LED Pin
# Validate LED Freq
# Validate LED DMA
elif current_device == "Fadecandy":
pass
# Validate server
elif not config.req_config_setting[current_device]:
pass
print(tests)
# def lineEdit(labelText, defaultText):
# wrapper = QWidget()
# hLayout = QHBoxLayout()
# wrapper.setLayout(hLayout)
# label = QLabel(labelText)
# lEdit = QLineEdit()
# lEdit.setPlaceholderText(defaultText)
# hLayout.addWidget(label)
# hLayout.addWidget(lEdit)
# return wrapper
# Set up window and layout
self.device_dialogue = QDialog(None, Qt.WindowSystemMenuHint | Qt.WindowCloseButtonHint)
self.device_dialogue.setWindowTitle("LED Strip Manager")
self.device_dialogue.setWindowModality(Qt.ApplicationModal)
layout = QVBoxLayout()
self.device_dialogue.setLayout(layout)
# Set up tab layouts
tabs = QTabWidget()
layout.addWidget(tabs)
addDeviceTab = QWidget()
remDeviceTab = QWidget()
addDeviceTabLayout = QVBoxLayout()
remDeviceTabLayout = QVBoxLayout()
addDeviceTabButtonLayout = QGridLayout()
remDeviceTabButtonLayout = QGridLayout()
addDeviceTab.setLayout(addDeviceTabLayout)
remDeviceTab.setLayout(remDeviceTabLayout)
tabs.addTab(addDeviceTab, "Add Device")
tabs.addTab(remDeviceTab, "Remove Device")
# Set up "Add Device" tab
device_type_cbox = QComboBox()
device_type_cbox.addItems(config.device_req_config.keys())
device_type_cbox.currentIndexChanged.connect(show_hide_addBoard_interface)
addDeviceTabLayout.addWidget(device_type_cbox)
# Set up "Add Device" widgets
widgets = {}
addDeviceTabLayout.addLayout(addDeviceTabButtonLayout)
remDeviceTabLayout.addLayout(remDeviceTabButtonLayout)
# if the new board has required config
for device in config.device_req_config:
# Make the widgets
widgets[device] = {}
if config.device_req_config[device]:
for req_config_setting in config.device_req_config[device]:
label = config.device_req_config[device][req_config_setting][0]
guide = config.device_req_config[device][req_config_setting][1]
wType = config.device_req_config[device][req_config_setting][2]
deflt = config.device_req_config[device][req_config_setting][3]
wLabel = QLabel(label)
#wGuide = QLabel(guide)
if wType == "textbox":
wEdit = QLineEdit()
wEdit.setPlaceholderText(deflt)
wEdit.textChanged.connect(validate_input)
elif wType == "checkbox":
wEdit = QCheckBox()
wEdit.setCheckState(Qt.Checked if deflt else Qt.Unchecked)
widgets[device][req_config_setting] = [wLabel, wEdit]
# Add widgets to layout
i = 0
for req_config in widgets[device]:
addDeviceTabButtonLayout.addWidget(widgets[device][req_config][0], i, 0)
addDeviceTabButtonLayout.addWidget(widgets[device][req_config][1], i, 1)
#addDeviceTabButtonLayout.addWidget(widget_set[2], i+1, 0, 1, 2)
i += 1
else:
no_setup = QLabel("Device requires no additional setup here! :)")
widgets[device]["no_config"] = no_setup
addDeviceTabButtonLayout.addWidget(no_setup, 0, 0)
# Show appropriate widgets
show_hide_addBoard_interface()
# self.gui_vis_checkboxes = {}
# for section in self.gui_widgets:
# self.gui_vis_checkboxes[section] = QCheckBox(section)
# self.gui_vis_checkboxes[section].setCheckState(
# Qt.Checked if config.settings["GUI_opts"][section] else Qt.Unchecked)
# self.gui_vis_checkboxes[section].stateChanged.connect(update_visibilty_dict)
# addDeviceTabLayout.addWidget(self.gui_vis_checkboxes[section])
self.add_device_button = QPushButton("Add Device")
addDeviceTabLayout.addWidget(self.add_device_button)
# Set up "Remove Device" tab
# Set up ok/cancel buttons
self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
self.buttons.accepted.connect(self.device_dialogue.accept)
self.buttons.rejected.connect(self.device_dialogue.reject)
layout.addWidget(self.buttons)
self.device_dialogue.show()
def saveDialogue(self):
# Save window state
settings.beginGroup("MainWindow")
settings.setValue("geometry", self.saveGeometry())
settings.setValue('state', self.saveState())
settings.endGroup()
# save all settings
settings.setValue("settings_dict", config.settings)
# save and close
settings.sync()
# Confirmation message
self.conf_dialogue = QMessageBox()
self.conf_dialogue.setText("Settings saved.\nSettings are also automatically saved when program closes.")
self.conf_dialogue.show()
def guiDialogue(self): def guiDialogue(self):
def update_visibilty_dict(): def update_visibilty_dict():
for checkbox in self.gui_vis_checkboxes: for checkbox in self.gui_vis_checkboxes:
@ -697,32 +904,7 @@ class GUI(QMainWindow):
self.updateUIVisibleItems() self.updateUIVisibleItems()
self.gui_dialogue = QDialog(None, Qt.WindowSystemMenuHint | Qt.WindowCloseButtonHint) self.gui_dialogue = QDialog(None, Qt.WindowSystemMenuHint | Qt.WindowCloseButtonHint)
self.gui_dialogue.setWindowTitle("GUI Properties") self.gui_dialogue.setWindowTitle("Show/hide Interface Sections")
self.gui_dialogue.setWindowModality(Qt.ApplicationModal)
layout = QGridLayout()
self.gui_dialogue.setLayout(layout)
# OK button
self.buttons = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self)
self.buttons.accepted.connect(self.gui_dialogue.accept)
self.gui_vis_checkboxes = {}
for section in self.gui_widgets:
self.gui_vis_checkboxes[section] = QCheckBox(section)
self.gui_vis_checkboxes[section].setCheckState(
Qt.Checked if config.settings["GUI_opts"][section] else Qt.Unchecked)
self.gui_vis_checkboxes[section].stateChanged.connect(update_visibilty_dict)
layout.addWidget(self.gui_vis_checkboxes[section])
layout.addWidget(self.buttons)
self.gui_dialogue.show()
def configDialogue(self):
def update_visibilty_dict():
for checkbox in self.gui_vis_checkboxes:
config.settings["GUI_opts"][checkbox] = self.gui_vis_checkboxes[checkbox].isChecked()
self.updateUIVisibleItems()
self.gui_dialogue = QDialog(None, Qt.WindowSystemMenuHint | Qt.WindowCloseButtonHint)
self.gui_dialogue.setWindowTitle("GUI Properties")
self.gui_dialogue.setWindowModality(Qt.ApplicationModal) self.gui_dialogue.setWindowModality(Qt.ApplicationModal)
layout = QGridLayout() layout = QGridLayout()
self.gui_dialogue.setLayout(layout) self.gui_dialogue.setLayout(layout)
@ -742,10 +924,10 @@ class GUI(QMainWindow):
def initBoardUI(self, board): def initBoardUI(self, board):
self.board = board self.board = board
# =============================================== Set up wrapping layout # Set up wrapping layout
self.board_tabs_widgets[board]["wrapper"] = QVBoxLayout() self.board_tabs_widgets[board]["wrapper"] = QVBoxLayout()
# ================================================== Set up graph layout # Set up graph layout
self.board_tabs_widgets[board]["graph_view"] = pg.GraphicsView() self.board_tabs_widgets[board]["graph_view"] = pg.GraphicsView()
graph_layout = pg.GraphicsLayout(border=(100,100,100)) graph_layout = pg.GraphicsLayout(border=(100,100,100))
self.board_tabs_widgets[board]["graph_view"].setCentralItem(graph_layout) self.board_tabs_widgets[board]["graph_view"].setCentralItem(graph_layout)
@ -780,7 +962,7 @@ class GUI(QMainWindow):
led_plot.addItem(self.board_tabs_widgets[board]["g_curve"]) led_plot.addItem(self.board_tabs_widgets[board]["g_curve"])
led_plot.addItem(self.board_tabs_widgets[board]["b_curve"]) led_plot.addItem(self.board_tabs_widgets[board]["b_curve"])
# ================================================= Set up button layout # Set up button layout
self.board_tabs_widgets[board]["label_reactive"] = QLabel("Audio Reactive Effects") self.board_tabs_widgets[board]["label_reactive"] = QLabel("Audio Reactive Effects")
self.board_tabs_widgets[board]["label_non_reactive"] = QLabel("Non Reactive Effects") self.board_tabs_widgets[board]["label_non_reactive"] = QLabel("Non Reactive Effects")
self.board_tabs_widgets[board]["reactive_button_grid_wrap"] = QWidget() self.board_tabs_widgets[board]["reactive_button_grid_wrap"] = QWidget()
@ -824,7 +1006,7 @@ class GUI(QMainWindow):
k = 0 k = 0
l += 1 l += 1
# ============================================== Set up frequency slider # Set up frequency slider
# Frequency range label # Frequency range label
self.board_tabs_widgets[board]["label_slider"] = QLabel("Frequency Range") self.board_tabs_widgets[board]["label_slider"] = QLabel("Frequency Range")
# Frequency slider # Frequency slider
@ -868,7 +1050,7 @@ class GUI(QMainWindow):
} }
""") """)
# ============================================ Set up option tabs layout # Set up option tabs layout
self.board_tabs_widgets[board]["label_options"] = QLabel("Effect Options") self.board_tabs_widgets[board]["label_options"] = QLabel("Effect Options")
self.board_tabs_widgets[board]["opts_tabs"] = QTabWidget() self.board_tabs_widgets[board]["opts_tabs"] = QTabWidget()
# Dynamically set up tabs # Dynamically set up tabs
@ -944,7 +1126,7 @@ class GUI(QMainWindow):
# ============================================= Add layouts into self.board_tabs_widgets[board]["wrapper"] # Add layouts into self.board_tabs_widgets[board]["wrapper"]
self.board_tabs_widgets[board]["wrapper"].addWidget(self.board_tabs_widgets[board]["graph_view"]) self.board_tabs_widgets[board]["wrapper"].addWidget(self.board_tabs_widgets[board]["graph_view"])
self.board_tabs_widgets[board]["wrapper"].addWidget(self.board_tabs_widgets[board]["label_reactive"]) self.board_tabs_widgets[board]["wrapper"].addWidget(self.board_tabs_widgets[board]["label_reactive"])
self.board_tabs_widgets[board]["wrapper"].addWidget(self.board_tabs_widgets[board]["reactive_button_grid_wrap"]) self.board_tabs_widgets[board]["wrapper"].addWidget(self.board_tabs_widgets[board]["reactive_button_grid_wrap"])
@ -1174,8 +1356,6 @@ def microphone_update(audio_samples):
gui.label_error.setText("") gui.label_error.setText("")
else: else:
gui.label_error.setText("No audio input. Volume below threshold.") gui.label_error.setText("No audio input. Volume below threshold.")
# Update fps counter
gui.label_fps.setText('{:.0f} / {:.0f} FPS'.format(fps, config.settings["configuration"]["FPS"]))
app.processEvents() app.processEvents()
# Left in just in case prople dont use the gui # Left in just in case prople dont use the gui
@ -1194,27 +1374,27 @@ visualizers = {}
boards = {} boards = {}
for board in config.settings["devices"]: for board in config.settings["devices"]:
visualizers[board] = Visualizer(board) visualizers[board] = Visualizer(board)
if config.settings["devices"][board]["configuration"]["TYPE"] == 'esp8266': if config.settings["devices"][board]["configuration"]["TYPE"] == 'ESP8266':
boards[board] = devices.ESP8266( boards[board] = devices.ESP8266(
auto_detect=config.settings["devices"][board]["configuration"]["AUTO_DETECT"], auto_detect=config.settings["devices"][board]["configuration"]["AUTO_DETECT"],
mac_addr=config.settings["devices"][board]["configuration"]["MAC_ADDR"], mac_addr=config.settings["devices"][board]["configuration"]["MAC_ADDR"],
ip=config.settings["devices"][board]["configuration"]["UDP_IP"], ip=config.settings["devices"][board]["configuration"]["UDP_IP"],
port=config.settings["devices"][board]["configuration"]["UDP_PORT"]) port=config.settings["devices"][board]["configuration"]["UDP_PORT"])
elif config.settings["devices"][board]["configuration"]["TYPE"] == 'pi': elif config.settings["devices"][board]["configuration"]["TYPE"] == 'RaspberryPi':
boards[board] = devices.RaspberryPi( boards[board] = devices.RaspberryPi(
n_pixels=config.settings["devices"][board]["configuration"]["N_PIXELS"], n_pixels=config.settings["devices"][board]["configuration"]["N_PIXELS"],
pin=config.settings["devices"][board]["configuration"]["LED_PIN"], pin=config.settings["devices"][board]["configuration"]["LED_PIN"],
invert_logic=config.settings["devices"][board]["configuration"]["LED_INVERT"], invert_logic=config.settings["devices"][board]["configuration"]["LED_INVERT"],
freq=config.settings["devices"][board]["configuration"]["LED_FREQ_HZ"], freq=config.settings["devices"][board]["configuration"]["LED_FREQ_HZ"],
dma=config.settings["devices"][board]["configuration"]["LED_DMA"]) dma=config.settings["devices"][board]["configuration"]["LED_DMA"])
elif config.settings["devices"][board]["configuration"]["TYPE"] == 'fadecandy': elif config.settings["devices"][board]["configuration"]["TYPE"] == 'Fadecandy':
boards[board] = devices.FadeCandy( boards[board] = devices.FadeCandy(
server=config.settings["devices"][board]["configuration"]["SERVER"]) server=config.settings["devices"][board]["configuration"]["SERVER"])
elif config.settings["devices"][board]["configuration"]["TYPE"] == 'blinkstick': elif config.settings["devices"][board]["configuration"]["TYPE"] == 'BlinkStick':
boards[board] = devices.BlinkStick() boards[board] = devices.BlinkStick()
elif config.settings["devices"][board]["configuration"]["TYPE"] == 'dotstar': elif config.settings["devices"][board]["configuration"]["TYPE"] == 'DotStar':
boards[board] = devices.DotStar() boards[board] = devices.DotStar()
elif config.settings["devices"][board]["configuration"]["TYPE"] == 'stripless': elif config.settings["devices"][board]["configuration"]["TYPE"] == 'Stripless':
pass pass
# Initialise DSP # Initialise DSP