Skip to content

Commit

Permalink
BROKEN VERSION: Added Beat Tunnel Mode
Browse files Browse the repository at this point in the history
  • Loading branch information
connornishijima committed Jun 12, 2024
1 parent 70799a5 commit ceee4db
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 55 deletions.
87 changes: 87 additions & 0 deletions src/EMOTISCOPE_FIRMWARE.ino.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# 1 "C:\\Users\\conno\\AppData\\Local\\Temp\\tmpncq9j96b"
#include <Arduino.h>
# 1 "C:/Users/conno/Emotiscope/src/EMOTISCOPE_FIRMWARE.ino"
# 55 "C:/Users/conno/Emotiscope/src/EMOTISCOPE_FIRMWARE.ino"
#define SOFTWARE_VERSION_MAJOR ( 1 )
#define SOFTWARE_VERSION_MINOR ( 2 )
#define SOFTWARE_VERSION_PATCH ( 0 )






#include <PsychicHttp.h>
#include <HTTPClient.h>
#include <ESPmDNS.h>
#include <Ticker.h>
#include <DNSServer.h>
#include <Preferences.h>
#include <Update.h>
#include <WiFi.h>
#include <esp_dsp.h>
#include <esp_wifi.h>


#include "global_defines.h"
#include "hardware_version.h"
#include "types.h"
#include "profiler.h"
#include "sliders.h"
#include "toggles.h"
#include "menu_toggles.h"
#include "menu_dropdowns.h"
#include "filesystem.h"
#include "configuration.h"
#include "utilities.h"
#include "system.h"
#include "led_driver.h"
#include "perlin.h"
#include "leds.h"
#include "touch.h"
#include "indicator.h"
#include "ui.h"
#include "microphone.h"
#include "vu.h"
#include "goertzel.h"
#include "tempo.h"
#include "screensaver.h"
#include "standby.h"
#include "light_modes.h"
#include "commands.h"
#include "wireless.h"
#include "ota.h"


#include "cpu_core.h"
#include "gpu_core.h"
#include "web_core.h"
# 117 "C:/Users/conno/Emotiscope/src/EMOTISCOPE_FIRMWARE.ino"
void loop();
void loop_gpu(void *param);
void setup();
#line 117 "C:/Users/conno/Emotiscope/src/EMOTISCOPE_FIRMWARE.ino"
void loop() {
run_cpu();
run_web();
}


void loop_gpu(void *param) {
for (;;) {

run_gpu();
run_gpu();
run_gpu();
run_gpu();
}
}


void setup() {

init_system();


(void)xTaskCreatePinnedToCore(loop_gpu, "loop_gpu", 4096, NULL, 0, NULL, 0);
}
2 changes: 1 addition & 1 deletion src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void load_config(){
strcpy(configuration.softness.ui_type_string, "s");
configuration.softness.type = f32;
configuration.softness.ui_type = ui_type_slider;
configuration.softness.value.f32 = 0.0;
configuration.softness.value.f32 = 0.33;
//configuration.softness.value.f32 = preferences.getFloat(configuration.softness.name, 0.25);

// Color
Expand Down
4 changes: 2 additions & 2 deletions src/global_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@
#define NOVELTY_HISTORY_LENGTH (1024)

// TEMPO_LOW to TEMPO_HIGH
#define NUM_TEMPI (96)
#define NUM_TEMPI (128)

// BPM range
#define TEMPO_LOW (40)
#define TEMPO_HIGH (TEMPO_LOW + NUM_TEMPI)

// How far forward or back in time the beat phase is shifted
#define BEAT_SHIFT_PERCENT (-0.08)
#define BEAT_SHIFT_PERCENT (0.00)

// Set later by physical traces on the PCB
uint8_t HARDWARE_VERSION = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/goertzel.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ void calculate_magnitudes() {
profile_function([&]() {
magnitudes_locked = true;

const uint16_t NUM_AVERAGE_SAMPLES = 2;
const uint16_t NUM_AVERAGE_SAMPLES = 1;

static float magnitudes_raw[NUM_FREQS];
static float magnitudes_noise_filtered[NUM_FREQS];
Expand Down
74 changes: 39 additions & 35 deletions src/leds.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,45 +61,50 @@ const uint8_t hsv_lookup[256][3] = {

extern float novelty_curve_normalized[NOVELTY_HISTORY_LENGTH];

void draw_sprite(float dest[], float sprite[], uint32_t dest_length, uint32_t sprite_length, float position, float alpha) {
int32_t position_whole = position; // Downcast to integer accuracy
float position_fract = position - position_whole;
float mix_right = position_fract;
float mix_left = 1.0 - mix_right;
void draw_sprite(CRGBF dest[], CRGBF sprite[], uint16_t dest_length, uint16_t sprite_length, float position, float alpha){
int16_t position_whole = floor(position); // Downcast to integer accuracy
float position_fract = fabsf(fabsf(position) - fabsf(position_whole));

for (uint16_t i = 0; i < sprite_length; i++) {
int32_t pos_left = i + position_whole;
int32_t pos_right = i + position_whole + 1;
for (int16_t i = 0; i < sprite_length; i++) {
int16_t pos_left = i + position_whole;
int16_t pos_right = i + position_whole + 1;

bool skip_left = false;
bool skip_right = false;
float mix_right = position_fract;
float mix_left = 1.0 - mix_right;

if (pos_left < 0) {
pos_left = 0;
skip_left = true;
}
if (pos_left > dest_length - 1) {
pos_left = dest_length - 1;
skip_left = true;
}
if (pos_left >= 0 && pos_left < dest_length) {
dest[pos_left].r += sprite[i].r * mix_left * alpha;
dest[pos_left].g += sprite[i].g * mix_left * alpha;
dest[pos_left].b += sprite[i].b * mix_left * alpha;
}

if (pos_right < 0) {
pos_right = 0;
skip_right = true;
}
if (pos_right > dest_length - 1) {
pos_right = dest_length - 1;
skip_right = true;
}
if (pos_right >= 0 && pos_right < dest_length) {
dest[pos_right].r += sprite[i].r * mix_right * alpha;
dest[pos_right].g += sprite[i].g * mix_right * alpha;
dest[pos_right].b += sprite[i].b * mix_right * alpha;
}
}
}

if (skip_left == false) {
dest[pos_left] += sprite[i] * mix_left * alpha;
}
void draw_sprite(float dest[], float sprite[], uint32_t dest_length, uint32_t sprite_length, float position, float alpha) {
int16_t position_whole = floor(position); // Downcast to integer accuracy
float position_fract = fabsf(fabsf(position) - fabsf(position_whole));

if (skip_right == false) {
dest[pos_right] += sprite[i] * mix_right * alpha;
}
}
for (int16_t i = 0; i < sprite_length; i++) {
int16_t pos_left = i + position_whole;
int16_t pos_right = i + position_whole + 1;

float mix_right = position_fract;
float mix_left = 1.0 - mix_right;

if (pos_left >= 0 && pos_left < dest_length) {
dest[pos_left] += sprite[i] * mix_left * alpha;
}

if (pos_right >= 0 && pos_right < dest_length) {
dest[pos_right] += sprite[i] * mix_right * alpha;
}
}
}

void save_leds_to_temp() {
Expand Down Expand Up @@ -438,9 +443,8 @@ void draw_dot(CRGBF* layer, uint16_t fx_dots_slot, CRGBF color, float position,
// Calculate distance moved and adjust brightness of spread accordingly
float position_difference = fabs(position - prev_position);
float spread_area = fmaxf( (sqrt(position_difference)) * NUM_LEDS, 1.0f );

// Draw the line representing the motion blur
draw_line(layer, prev_position, position, color, (1.0) * opacity);
draw_line(layer, prev_position, position, color, (1.0 / spread_area) * opacity);
}

void update_auto_color(){
Expand Down
4 changes: 4 additions & 0 deletions src/light_modes.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Functions for outputting computed data in beautiful fashion to the LEDs based on
#include "light_modes/active/hype.h"
#include "light_modes/active/bloom.h"
#include "light_modes/active/fft.h"
#include "light_modes/active/tempiscope.h"
#include "light_modes/active/beat_tunnel.h"
// #include "light_modes/active/perlin.h"

// INACTIVE MODES
Expand All @@ -46,6 +48,8 @@ light_mode light_modes[] = {
{ "Hype", LIGHT_MODE_TYPE_ACTIVE, &draw_hype },
{ "Bloom", LIGHT_MODE_TYPE_ACTIVE, &draw_bloom },
{ "FFT", LIGHT_MODE_TYPE_ACTIVE, &draw_fft },
{ "Tempiscope", LIGHT_MODE_TYPE_ACTIVE, &draw_tempiscope },
{ "Beat Tunnel", LIGHT_MODE_TYPE_ACTIVE, &draw_beat_tunnel },
//{ "Perlin", LIGHT_MODE_TYPE_ACTIVE, &draw_perlin },

// Inactive Modes
Expand Down
43 changes: 43 additions & 0 deletions src/light_modes/active/beat_tunnel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
CRGBF tunnel_image[NUM_LEDS] = { 0.0 };
CRGBF tunnel_image_prev[NUM_LEDS] = { 0.0 };
float angle = 0.0;

void draw_beat_tunnel(){
memset(tunnel_image, 0, sizeof(CRGBF)*NUM_LEDS);

angle += 0.001;

float spread_speed = (0.125 + 0.875*configuration.speed.value.f32)*(sin(angle))*0.5;
draw_sprite(tunnel_image, tunnel_image_prev, NUM_LEDS, NUM_LEDS, spread_speed, 0.965);

for(uint16_t i = 0; i < NUM_TEMPI; i++){
float phase = 1.0 - ((tempi[i].phase + PI) / (2.0*PI));

float mag = 0.0;
if( fabs(phase - 0.65) < 0.02 ){
mag = clip_float(tempi_smooth[i]);
}

CRGBF tempi_color = hsv(
get_color_range_hue(num_tempi_float_lookup[i]),
configuration.saturation.value.f32,
(mag)
);

tunnel_image[i].r += tempi_color.r;
tunnel_image[i].g += tempi_color.g;
tunnel_image[i].b += tempi_color.b;
}

if(configuration.mirror_mode.value.u32 == true){
for(uint16_t i = 0; i < NUM_TEMPI-2; i++){
leds[ (NUM_LEDS>>1) + ((i+2)>>1)] = tunnel_image[i];
leds[((NUM_LEDS>>1)-1) - ((i+2)>>1)] = tunnel_image[i];
}
}
else{
memcpy(leds, tunnel_image, sizeof(CRGBF)*NUM_LEDS);
}

memcpy(tunnel_image_prev, tunnel_image, sizeof(CRGBF)*NUM_LEDS);
}
2 changes: 1 addition & 1 deletion src/light_modes/active/fft.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void draw_fft(){
float fft_max_mag = 0.0;
for(uint16_t i = 0; i < NUM_LEDS; i++){
if(i >= 4){
fft_mags[i] = fft_output[i];
fft_mags[i] = fft_smooth[0][i];
fft_max_mag = fmaxf(fft_max_mag, fft_mags[i]);
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/light_modes/active/tempiscope.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
void draw_tempiscope(){
// Draw the current frame
for(uint16_t i = 0; i < NUM_TEMPI; i++){
float progress = num_leds_float_lookup[i];

float sine = 1.0 - ((tempi[i].phase + PI) / (2.0*PI));

float mag = clip_float(tempi_smooth[i] * sine);

if(mag > 0.005){
CRGBF color = hsv(
get_color_range_hue(progress),
configuration.saturation.value.f32,
mag
);

leds[i] = color;
}
}
}
19 changes: 19 additions & 0 deletions src/microphone.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ float fft_output[FFT_SIZE];
__attribute__((aligned(16)))
float fft_max[FFT_SIZE];

__attribute__((aligned(16)))
const uint8_t num_fft_average_samples = 4;
float fft_smooth[1 + num_fft_average_samples][FFT_SIZE]; // One slot for output, others for averaging
uint16_t fft_averaging_index = 1;

void perform_fft(){
memset(fft_input_complex, 0, sizeof(float) * (FFT_SIZE << 1));

Expand Down Expand Up @@ -81,6 +86,19 @@ void perform_fft(){

fft_max[i] = fmaxf(fft_max[i], fft_output[i]);
}

memcpy(fft_smooth[ fft_averaging_index ], fft_output, sizeof(float) * FFT_SIZE);
fft_averaging_index += 1;
if(fft_averaging_index >= num_fft_average_samples + 1){
fft_averaging_index = 1;
}

memset(fft_smooth[0], 0, sizeof(float) * FFT_SIZE);
for(uint8_t i = 1; i < num_fft_average_samples + 1; i++){
dsps_add_f32(fft_smooth[0], fft_smooth[i], fft_smooth[0], FFT_SIZE, 1, 1, 1);
}

dsps_mulc_f32_ansi(fft_smooth[0], fft_smooth[0], FFT_SIZE, 1.0 / num_fft_average_samples, 1, 1);
}

void init_i2s_microphone(){
Expand Down Expand Up @@ -159,6 +177,7 @@ void acquire_sample_chunk() {
waveform_locked = true;
shift_and_copy_arrays(sample_history, SAMPLE_HISTORY_LENGTH, new_samples, CHUNK_SIZE*2);

// Perform FFT on the new audio data
perform_fft();

// Used to sync GPU to this when needed
Expand Down
Loading

0 comments on commit ceee4db

Please sign in to comment.