Skip to content

Commit a27d5db

Browse files
3.2.0 Update
1 parent e355d63 commit a27d5db

File tree

13 files changed

+1102
-590
lines changed

13 files changed

+1102
-590
lines changed

SENSORY_BRIDGE_FIRMWARE/GDFT.h

Lines changed: 113 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@
5858
// Obscure audio magic happens here
5959
void IRAM_ATTR process_GDFT() {
6060
static bool interlace_flip = false;
61-
interlace_flip = !interlace_flip; // Switch field every frame on lower notes to save execution time
62-
61+
interlace_flip = !interlace_flip; // Switch field every frame on lower notes to save execution time
62+
6363
// Reset magnitude caps every frame
6464
for (uint8_t i = 0; i < NUM_ZONES; i++) {
65-
max_mags[i] = CONFIG.MAGNITUDE_FLOOR; // Higher than the average noise floor
65+
max_mags[i] = CONFIG.MAGNITUDE_FLOOR / CONFIG.SENSITIVITY; // Higher than the average noise floor
6666
}
6767

6868
// Increment spectrogram history index
@@ -73,10 +73,10 @@ void IRAM_ATTR process_GDFT() {
7373

7474
// Run GDFT (Goertzel-based Discrete Fourier Transform) with 64 frequencies
7575
// Fixed-point code adapted from example here: https://sourceforge.net/p/freetel/code/HEAD/tree/misc/goertzal/goertzal.c
76-
for (uint16_t i = 0; i < NUM_FREQS; i++) { // Run 64 times
77-
bool field = bitRead(i, 0); // odd or even
76+
for (uint16_t i = 0; i < NUM_FREQS; i++) { // Run 64 times
77+
bool field = bitRead(i, 0); // odd or even
7878

79-
// If note is part of field being rendered, is >= index 16, or is the first note
79+
// If note is part of field being rendered, is >= index 16, or is the first note
8080
if (field == interlace_flip || i >= 16) {
8181
int32_t q0, q1, q2;
8282
int64_t mult;
@@ -85,9 +85,10 @@ void IRAM_ATTR process_GDFT() {
8585
q2 = 0;
8686

8787
float window_pos = 0.0;
88-
for (uint16_t n = 0; n < frequencies[i].block_size; n++) { // Run Goertzel for "block_size" iterations
88+
for (uint16_t n = 0; n < frequencies[i].block_size; n++) { // Run Goertzel for "block_size" iterations
8989
int32_t sample = 0;
90-
sample = ((int32_t)sample_window[SAMPLE_HISTORY_LENGTH - 1 - n] * (int32_t)window_lookup[uint16_t(window_pos)]) >> 16;
90+
//sample = ((int32_t)sample_window[SAMPLE_HISTORY_LENGTH - 1 - n] * (int32_t)window_lookup[uint16_t(window_pos)]) >> 16;
91+
sample = (int32_t)sample_window[SAMPLE_HISTORY_LENGTH - 1 - n];
9192
mult = (int64_t)frequencies[i].coeff_q14 * (int64_t)q1;
9293
q0 = (sample >> 6) + (mult >> 14) - q2;
9394
q2 = q1;
@@ -97,7 +98,7 @@ void IRAM_ATTR process_GDFT() {
9798
}
9899

99100
mult = (int64_t)frequencies[i].coeff_q14 * (int64_t)q1;
100-
magnitudes[i] = q2 * q2 + q1 * q1 - ((int32_t)(mult >> 14)) * q2; // Calculate raw magnitudes
101+
magnitudes[i] = q2 * q2 + q1 * q1 - ((int32_t)(mult >> 14)) * q2; // Calculate raw magnitudes
101102

102103
// Normalize output
103104
magnitudes[i] *= float(frequencies[i].block_size_recip);
@@ -110,7 +111,7 @@ void IRAM_ATTR process_GDFT() {
110111
}
111112
magnitudes[i] *= prog;
112113

113-
if (magnitudes[i] < 0.0) { // Prevent negative values
114+
if (magnitudes[i] < 0.0) { // Prevent negative values
114115
magnitudes[i] = 0.0;
115116
}
116117
}
@@ -139,23 +140,27 @@ void IRAM_ATTR process_GDFT() {
139140
}
140141
}
141142
noise_iterations++;
142-
if (noise_iterations >= 256) { // Calibration complete
143+
if (noise_iterations >= 1024) { // Calibration complete
143144
noise_complete = true;
144145
USBSerial.println("NOISE CAL COMPLETE");
145-
CONFIG.DC_OFFSET = dc_offset_sum / 256.0; // Calculate average DC offset and store it
146-
save_ambient_noise_calibration(); // Save results to noise_cal.bin
147-
save_config(); // Save config to config.bin
146+
CONFIG.DC_OFFSET = dc_offset_sum / 1024.0; // Calculate average DC offset and store it
147+
save_ambient_noise_calibration(); // Save results to noise_cal.bin
148+
save_config(); // Save config to config.bin
148149
}
149150
}
150151

151152
// Apply noise reduction data, estimate max values
152153
for (uint8_t i = 0; i < NUM_FREQS; i += 1) {
153154
if (noise_complete == true) {
154-
magnitudes[i] -= noise_samples[i] * 1.2; // Treat noise 1.2x louder than calibration
155+
magnitudes[i] -= noise_samples[i] * 1.5; // Treat noise 1.5x louder than calibration
155156
if (magnitudes[i] < 0.0) {
156157
magnitudes[i] = 0.0;
157158
}
158159
}
160+
}
161+
162+
for (uint8_t i = 0; i < NUM_FREQS; i++) {
163+
//magnitudes[i] *= magnitude_scale;
159164

160165
mag_targets[i] = magnitudes[i];
161166
if (mag_targets[i] > max_mags[frequencies[i].zone]) {
@@ -236,12 +241,12 @@ void IRAM_ATTR process_GDFT() {
236241
for (uint8_t i = 0; i < NUM_FREQS; i += 1) {
237242
if (mag_targets[i] > mag_followers[i]) {
238243
float delta = mag_targets[i] - mag_followers[i];
239-
mag_followers[i] += delta * (smoothing_follower * 0.45);
244+
mag_followers[i] += delta * (smoothing_follower * 0.65);
240245
}
241246

242247
else if (mag_targets[i] < mag_followers[i]) {
243248
float delta = mag_followers[i] - mag_targets[i];
244-
mag_followers[i] -= delta * (smoothing_follower * 0.55);
249+
mag_followers[i] -= delta * (smoothing_follower * 0.75);
245250
}
246251
}
247252

@@ -250,11 +255,11 @@ void IRAM_ATTR process_GDFT() {
250255
for (uint8_t i = 0; i < NUM_ZONES; i++) {
251256
if (max_mags[i] > max_mags_followers[i]) {
252257
float delta = max_mags[i] - max_mags_followers[i];
253-
max_mags_followers[i] += delta * 0.05;
258+
max_mags_followers[i] += delta * 0.0125;
254259
}
255260
if (max_mags[i] < max_mags_followers[i]) {
256261
float delta = max_mags_followers[i] - max_mags[i];
257-
max_mags_followers[i] -= delta * 0.05;
262+
max_mags_followers[i] -= delta * 0.0125;
258263
}
259264
}
260265

@@ -269,12 +274,21 @@ void IRAM_ATTR process_GDFT() {
269274
USBSerial.println("))");
270275
}
271276

277+
float max_mag = CONFIG.MAGNITUDE_FLOOR / CONFIG.SENSITIVITY;
278+
for (uint8_t i = 0; i < NUM_ZONES; i++) {
279+
if (max_mags_followers[i] > max_mag) {
280+
max_mag = max_mags_followers[i];
281+
}
282+
}
283+
272284
// Make Spectrogram from raw magnitudes
273285
for (uint8_t i = 0; i < NUM_FREQS; i += 1) {
274286
// Normalize our frequency bins to 0.0-1.0 range, which acts like an audio compressor at the same time
275287
float max_mag = interpolate(i / float(NUM_FREQS), max_mags_followers, NUM_ZONES);
276288
float mag_float = mag_followers[i] / max_mag;
277289

290+
//mag_float *= 2.0;
291+
278292
// Restrict range, allowing for clipped values at peaks and valleys
279293
if (mag_float < 0.0) {
280294
mag_float = 0.0;
@@ -286,37 +300,50 @@ void IRAM_ATTR process_GDFT() {
286300
mag_float = mag_float * (1.0 - smoothing_exp_average) + mag_float_last[i] * smoothing_exp_average;
287301
mag_float_last[i] = mag_float;
288302

289-
mag_float *= (CONFIG.GAIN);
303+
//mag_float *= (CONFIG.GAIN);
290304
if (mag_float > 1.0) {
291305
mag_float = 1.0;
292306
}
293307

308+
mag_float = sqrt(sqrt(mag_float));
309+
294310
note_spectrogram[i] = mag_float; // This array is the current value
295311
spectrogram_history[spectrogram_history_index][i] = note_spectrogram[i]; // This array is the value's history
296312
}
313+
}
297314

315+
float calc_punch(uint8_t low_bin, uint8_t high_bin) {
316+
const float push_max = 100000.0;
317+
float punch_pos_decay = 0.0;
298318

299-
// Make Chromagram
300-
chromagram_max_val = 0.0;
301-
for (uint8_t i = 0; i < 12; i++) {
302-
note_chromagram[i] = 0;
303-
}
304-
for (uint8_t octave = 0; octave < 6; octave++) {
305-
for (uint8_t note = 0; note < 12; note++) {
306-
uint16_t note_index = 12 * octave + note;
307-
if (note_index < NUM_FREQS && note_index < CONFIG.CHROMAGRAM_RANGE) {
308-
note_chromagram[note] += note_spectrogram[note_index] * 0.5;
319+
float smoothing = 0.128;
320+
float punch_pos = 0.0;
309321

310-
if (note_chromagram[note] > 1.0) {
311-
note_chromagram[note] = 1.0;
312-
}
322+
float punch_scaling = NUM_FREQS / (high_bin - low_bin);
313323

314-
if (note_chromagram[note] > chromagram_max_val) {
315-
chromagram_max_val = note_chromagram[note];
316-
}
317-
}
324+
for (uint8_t i = low_bin; i < high_bin; i++) {
325+
float delta = spectrogram_history[2][i] * spectrogram_history[2][i] - spectrogram_history[0][i] * spectrogram_history[0][i];
326+
if (delta < 0.0) {
327+
delta = 0.0;
318328
}
329+
punch_pos += (delta * punch_scaling);
330+
}
331+
332+
if (punch_pos > 1.0) {
333+
punch_pos = 1.0;
334+
}
335+
336+
float punch_pos_smooth = 0.0;
337+
punch_pos_smooth = punch_pos * (smoothing) + punch_pos_smooth * (1.0 - smoothing);
338+
339+
punch_pos_decay *= 0.9;
340+
341+
if (punch_pos_smooth > punch_pos_decay) {
342+
punch_pos_decay = punch_pos_smooth;
319343
}
344+
345+
float punch = push_max * (punch_pos_decay * punch_pos_decay * punch_pos_decay * punch_pos_decay * punch_pos_decay);
346+
return punch;
320347
}
321348

322349
void lookahead_smoothing() {
@@ -372,6 +399,40 @@ void lookahead_smoothing() {
372399
note_spectrogram_long_term[i] = (note_spectrogram_long_term[i] * 0.95) + (note_spectrogram_smooth[i] * 0.05);
373400
}
374401

402+
for (uint8_t i = 0; i < NATIVE_RESOLUTION; i++) {
403+
//note_spectrogram_smooth[i] = (note_spectrogram_smooth[i] + note_spectrogram_smooth_frame_blending[i]) * 0.5;
404+
405+
if (note_spectrogram_smooth[i] > 1.0) {
406+
note_spectrogram_smooth[i] = 1.0;
407+
}
408+
409+
note_spectrogram_smooth_frame_blending[i] = note_spectrogram_smooth[i];
410+
}
411+
412+
// Make Chromagram
413+
chromagram_max_val = 0.0;
414+
for (uint8_t i = 0; i < 12; i++) {
415+
note_chromagram[i] = 0;
416+
}
417+
418+
for (uint8_t octave = 0; octave < 6; octave++) {
419+
for (uint8_t note = 0; note < 12; note++) {
420+
uint16_t note_index = 12 * octave + note;
421+
if (note_index < NUM_FREQS && note_index < CONFIG.CHROMAGRAM_RANGE) {
422+
if (note_spectrogram_smooth[note_index] > note_chromagram[note]) {
423+
note_chromagram[note] = note_spectrogram_smooth[note_index];
424+
}
425+
426+
if (note_chromagram[note] > chromagram_max_val) {
427+
chromagram_max_val = note_chromagram[note];
428+
}
429+
}
430+
}
431+
}
432+
433+
// Calculate "punch" of the full frequency range (used by auto color-cycling)
434+
current_punch = calc_punch(0, NUM_FREQS); // (lightshow_modes.h)
435+
375436
if (stream_spectrogram == true) {
376437
if (serial_iter >= 2) { // Don't print every frame
377438
serial_iter = 0;
@@ -386,4 +447,19 @@ void lookahead_smoothing() {
386447
USBSerial.println("))");
387448
}
388449
}
450+
451+
if (stream_chromagram == true) {
452+
if (serial_iter >= 2) { // Don't print every frame
453+
serial_iter = 0;
454+
USBSerial.print("sbs((chromagram=");
455+
for (uint16_t i = 0; i < 12; i++) {
456+
uint16_t bin = 999 * note_chromagram[i];
457+
USBSerial.print(bin);
458+
if (i < 12 - 1) {
459+
USBSerial.print(',');
460+
}
461+
}
462+
USBSerial.println("))");
463+
}
464+
}
389465
}

0 commit comments

Comments
 (0)