Skip to content

Commit

Permalink
3.0.0-beta3 upload
Browse files Browse the repository at this point in the history
  • Loading branch information
connornishijima committed Jan 19, 2023
1 parent d34e6ac commit 23a3f95
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 95 deletions.
29 changes: 25 additions & 4 deletions SENSORY_BRIDGE_FIRMWARE/GDFT.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,36 @@ void IRAM_ATTR process_GDFT() {


// Make Chromagram
chromagram_max_val = 0.0;
chromagram_bass_max_val = 0.0;
for (uint8_t i = 0; i < 12; i++) {
note_chromagram[i] = 0;
note_chromagram_bass[i] = 0;
}
for (uint8_t note = 0; note < 12; note++) {
for (uint8_t octave = 0; octave < 6; octave++) {
for (uint8_t octave = 0; octave < 6; octave++) {
for (uint8_t note = 0; note < 12; note++) {
uint16_t note_index = 12 * octave + note;
if (note_index < NUM_FREQS) {
if (note_spectrogram[note_index] > note_chromagram[note]) {
note_chromagram[note] = note_spectrogram[note_index];
note_chromagram[note] += note_spectrogram[note_index]*0.5;

if (note_chromagram[note] > 1.0) {
note_chromagram[note] = 1.0;
}

if (note_chromagram[note] > chromagram_max_val) {
chromagram_max_val = note_chromagram[note];
}

if (note_index < 12) {
note_chromagram_bass[note] += note_spectrogram[note_index];

if (note_chromagram_bass[note] > 1.0) {
note_chromagram_bass[note] = 1.0;
}

if (note_chromagram_bass[note] > chromagram_bass_max_val) {
chromagram_bass_max_val = 1.0; //note_chromagram_bass[note];
}
}
}
}
Expand Down
14 changes: 11 additions & 3 deletions SENSORY_BRIDGE_FIRMWARE/SENSORY_BRIDGE_FIRMWARE.ino
Original file line number Diff line number Diff line change
Expand Up @@ -132,19 +132,23 @@ void loop() {
// Capture a frame of I2S audio (holy crap, FINALLY something about sound)

function_id = 6;
run_sweet_spot(); // (led_utilities.h)
// Based on the current audio volume, alter the Sweet Spot indicator LEDs

function_id = 7;
process_GDFT(); // (GDFT.h)
// Execute GDFT and post-process
// (If you're wondering about that weird acronym, check out the source file)

function_id = 7;
function_id = 8;
lookahead_smoothing(); // (GDFT.h)
// Peek at upcoming frames to study/prevent flickeringd

function_id = 8;
function_id = 9;
render_leds(t_now_us); // (BELOW in this file)
// Convert the data we found into a beautiful show

function_id = 9;
function_id = 10;
log_fps(t_now_us); // (system.h)
// Log the current FPS

Expand All @@ -161,6 +165,10 @@ void loop() {
// different rendering function from lightshow_modes.h:
void render_leds(uint32_t t_now_us) {
if (noise_complete == true) { // If we're not gathering ambient noise data
if (mode_transition_queued == true || noise_transition_queued == true) {
run_transition_fade(); // (led_utilities.h) Fade to black between modes
}

if (CONFIG.LIGHTSHOW_MODE == LIGHT_MODE_GDFT) {
light_mode_gdft(); // (lightshow_modes.h) GDFT spectrogram display
} else if (CONFIG.LIGHTSHOW_MODE == LIGHT_MODE_GDFT_CHROMAGRAM) {
Expand Down
53 changes: 20 additions & 33 deletions SENSORY_BRIDGE_FIRMWARE/buttons.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*----------------------------------------
Sensory Bridge BUTTON FUNCTIONS
----------------------------------------*/
----------------------------------------*/

// Every frame, we check both buttons for two types of input:
//
Expand Down Expand Up @@ -40,29 +40,9 @@ void check_buttons(uint32_t t_now) {

uint32_t press_duration = noise_button.last_up - noise_button.last_down; // Get press duration

if (press_duration < 250) { // if it was a short press
if (press_duration <= 250) { // if it was a short press
if (CONFIG.IS_MAIN_UNIT || main_override) { // if main unit, start noise cal
Serial.println("COLLECTING AMBIENT NOISE SAMPLES IN 500 MS");
noise_complete = false;

clear_all_led_buffers();
CONFIG.DC_OFFSET = 0;
CONFIG.WAVEFORM_NOISE_FLOOR = 0;

for (uint16_t i = 0; i < 128; i++) {
for (uint16_t x = 0; x < 128; x++) {
leds[x] = CRGB(0, 0, 0);
}
uint16_t ir = 127 - i;
leds[ir] = CRGB(0, 255, 255);
show_leds();
}

clear_all_led_buffers();
show_leds();

propagate_noise_cal();
start_noise_cal();
noise_transition_queued = true; // See run_transition_fade() in led_utilities.h
}
else { // Otherwise, complain
identify_main_unit();
Expand Down Expand Up @@ -92,20 +72,27 @@ void check_buttons(uint32_t t_now) {
if (mode_button.pressed == true) {
mode_button.pressed = false;
mode_button.last_up = t_now;
bool skip_click = false;

if (mode_transition_queued == true) {
skip_click = true;
mode_transition_queued = false;
MASTER_BRIGHTNESS = 1.0;
Serial.println("DOUBLE CLICK");
}

uint32_t press_duration = mode_button.last_up - mode_button.last_down;

if (press_duration < 250) {
if (CONFIG.IS_MAIN_UNIT || main_override) {
CONFIG.LIGHTSHOW_MODE++;
if (CONFIG.LIGHTSHOW_MODE >= NUM_MODES) {
CONFIG.LIGHTSHOW_MODE = 0;
}
if (press_duration <= 250 && skip_click == false) {
if (mode_transition_queued == false) {
if (CONFIG.IS_MAIN_UNIT || main_override) {
mode_transition_queued = true; // See run_transition_fade() in led_utilities.h

last_setting_change = millis();
settings_updated = true;
} else {
identify_main_unit();
last_setting_change = millis();
settings_updated = true;
} else {
identify_main_unit();
}
}
}
}
Expand Down
22 changes: 21 additions & 1 deletion SENSORY_BRIDGE_FIRMWARE/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ struct conf {
float BASE_HUE;
uint8_t LIGHTSHOW_MODE;
bool MIRROR_ENABLED;
bool CHROMAGRAM_BASS;

// Private values
uint32_t SAMPLE_RATE;
Expand All @@ -21,6 +22,8 @@ struct conf {
uint16_t SAMPLES_PER_CHUNK;
float GAIN;
bool BOOT_ANIMATION;
uint16_t SWEET_SPOT_MIN_LEVEL;
uint16_t SWEET_SPOT_MAX_LEVEL;
int32_t DC_OFFSET; // (TODO)
uint32_t WAVEFORM_NOISE_FLOOR; // (TODO)
uint8_t ESPNOW_CHANNEL; // (TODO)
Expand All @@ -37,6 +40,7 @@ conf CONFIG = { // Defaults of the CONFIG struct
0.00, // BASE_HUE
LIGHT_MODE_GDFT, // LIGHTSHOW_MODE
true, // MIRROR_ENABLED (>= 3.0.0 defaults yes)
false, // CHROMAGRAM_BASS

// Private values
DEFAULT_SAMPLE_RATE, // SAMPLE_RATE
Expand All @@ -49,6 +53,8 @@ conf CONFIG = { // Defaults of the CONFIG struct
256, // SAMPLES_PER_CHUNK
0.0, // GAIN
true, // BOOT_ANIMATION
750, // SWEET_SPOT_MIN_LEVEL
30000, // SWEET_SPOT_MAX_LEVEL
0, // DC_OFFSET
0, // WAVEFORM_NOISE_FLOOR
3, // ESPNOW_CHANNEL
Expand Down Expand Up @@ -106,6 +112,9 @@ float note_spectrogram[NUM_FREQS] = {0};
float note_spectrogram_smooth[NUM_FREQS] = {0};
float note_spectrogram_long_term[NUM_FREQS] = {0};
float note_chromagram[12] = {0};
float note_chromagram_bass[12] = {0};
float chromagram_max_val = 0.0;
float chromagram_bass_max_val = 0.0;

float smoothing_follower = 0.0;
float smoothing_exp_average = 0.0;
Expand All @@ -115,7 +124,15 @@ float smoothing_exp_average = 0.0;

int32_t i2s_samples_raw[1024] = { 0 };
short sample_window[SAMPLE_HISTORY_LENGTH] = { 0 };
short sample_chunk[1024] = { 0 };
short waveform[1024] = { 0 };
float max_waveform_val = 0.0;
float max_waveform_val_follower = 0.0;
float waveform_peak_scaled = 0.0;

// ------------------------------------------------------------
// Sweet Spot (i2s_audio.h, led_utilities.h) ------------------
float sweet_spot_state = 0;
float sweet_spot_state_follower = 0;

// ------------------------------------------------------------
// Noise calibration (noise_cal.h) ----------------------------
Expand Down Expand Up @@ -162,6 +179,9 @@ struct button{
button noise_button;
button mode_button;

bool mode_transition_queued = false;
bool noise_transition_queued = false;

// ------------------------------------------------------------
// Settings tracking (system.h) -------------------------------

Expand Down
64 changes: 50 additions & 14 deletions SENSORY_BRIDGE_FIRMWARE/i2s_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,38 +57,74 @@ void acquire_sample_chunk() {
size_t bytes_read = 0;
i2s_read(I2S_PORT, i2s_samples_raw, CONFIG.SAMPLES_PER_CHUNK * sizeof(int32_t), &bytes_read, portMAX_DELAY);

max_waveform_val = 0.0;

// Scale I2S samples and store into history
for (uint16_t i = 0; i < CONFIG.SAMPLES_PER_CHUNK; i++) {
float sample = (i2s_samples_raw[i] * 0.000512) + 56000 - 5120;
int32_t sample = (i2s_samples_raw[i] * 0.000512) + 56000 - 5120;

sample = sample >> 2;

if (sample > 32767) { //clipping
sample = 32767;
} else if (sample < -32767) {
sample = -32767;
}

int16_t sample_abs = abs(sample)-(CONFIG.SWEET_SPOT_MIN_LEVEL>>1);
if(sample_abs > max_waveform_val){
max_waveform_val = sample_abs;
}

sample_chunk[i] = sample/2;
waveform[i] = sample;

if (stream_audio == true) {
Serial.println(sample);
}
}

if(max_waveform_val > max_waveform_val_follower){
float delta = max_waveform_val - max_waveform_val_follower;
max_waveform_val_follower += delta*0.25;
}
else if(max_waveform_val < max_waveform_val_follower){
float delta = max_waveform_val_follower - max_waveform_val;
max_waveform_val_follower -= delta*0.0025;

if(max_waveform_val_follower < CONFIG.SWEET_SPOT_MIN_LEVEL){
max_waveform_val_follower = CONFIG.SWEET_SPOT_MIN_LEVEL;
}
}
float waveform_peak_scaled_raw = max_waveform_val/max_waveform_val_follower;

if(waveform_peak_scaled_raw > waveform_peak_scaled){
float delta = waveform_peak_scaled_raw - waveform_peak_scaled;
waveform_peak_scaled += delta*0.25;
}
else if(waveform_peak_scaled_raw < waveform_peak_scaled){
float delta = waveform_peak_scaled - waveform_peak_scaled_raw;
waveform_peak_scaled -= delta*0.25;
}

// Use the maximum amplitude of the captured frame to set
// the Sweet Spot state. Think of this like a coordinate
// space where 0 is the center LED, -1 is the left, and
// +1 is the right. See run_sweet_spot() in led_utilities.h
// for how this value translates to the final LED brightnesses
if(max_waveform_val <= CONFIG.SWEET_SPOT_MIN_LEVEL){
sweet_spot_state = -1;
}
else if(max_waveform_val >= CONFIG.SWEET_SPOT_MAX_LEVEL){
sweet_spot_state = 1;
}
else{
sweet_spot_state = 0;
}

for (int i = 0; i < SAMPLE_HISTORY_LENGTH - CONFIG.SAMPLES_PER_CHUNK; i++) {
sample_window[i] = sample_window[i + CONFIG.SAMPLES_PER_CHUNK];
}
for (int i = SAMPLE_HISTORY_LENGTH - CONFIG.SAMPLES_PER_CHUNK; i < SAMPLE_HISTORY_LENGTH; i++) {
sample_window[i] = sample_chunk[i - (SAMPLE_HISTORY_LENGTH - CONFIG.SAMPLES_PER_CHUNK)];
}

/*
iter++;
if(iter >= 1000){
iter = 0;
for(uint16_t i = 0; i < SAMPLE_HISTORY_LENGTH; i++){
Serial.println(sample_window[i]);
delay(10);
}
sample_window[i] = waveform[i - (SAMPLE_HISTORY_LENGTH - CONFIG.SAMPLES_PER_CHUNK)];
}
*/
}
5 changes: 1 addition & 4 deletions SENSORY_BRIDGE_FIRMWARE/knobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void check_knobs(uint32_t t_now) {
}

// This is only used to fade in when booting!
if(t_now >= 1000){
if(t_now >= 1000 && noise_transition_queued == false && mode_transition_queued == false){
if(MASTER_BRIGHTNESS < 1.0){
MASTER_BRIGHTNESS += 0.01;
}
Expand Down Expand Up @@ -116,7 +116,4 @@ void check_knobs(uint32_t t_now) {
// These are the final values we'll feed into the two smoothing algorithms soon
smoothing_follower = 0.225 + (smoothing_top_half * 0.275); // 0.0-1.0 input range becomes 0.225-0.500
smoothing_exp_average = 1.0 - smoothing_bottom_half; // invert input

// PHOTONS knob is squared and applied here:
FastLED.setBrightness((255 * MASTER_BRIGHTNESS) * (CONFIG.PHOTONS * CONFIG.PHOTONS));
}
Loading

0 comments on commit 23a3f95

Please sign in to comment.