forked from buddhabrot/fusion-zauberstab
fackel reversed und gekuerzt
This commit is contained in:
parent
ff350437e3
commit
54bddbfc4f
@ -12,12 +12,6 @@ struct BeatDetectApp : public App {
|
|||||||
void loop();
|
void loop();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FftDetectApp : public App {
|
|
||||||
void init();
|
|
||||||
void deinit();
|
|
||||||
void loop();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct VuMeterApp: public App {
|
struct VuMeterApp: public App {
|
||||||
void init();
|
void init();
|
||||||
|
@ -58,7 +58,7 @@ get_value(int pos, float pos0)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (40 - abs(pos0 - pos) * 8);
|
return (30 - abs(pos0 - pos) * 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ set_filter()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < n_BP; i++)
|
for (int i = 0; i < n_BP; i++)
|
||||||
{
|
{
|
||||||
float frequency = 1.75 + i * (2.4 - 1.75) / n_BP;
|
float frequency = 1.75 + i * (2.5 - 1.75) / n_BP;
|
||||||
float a, a0, a1, a2, b0, b1, b2, w0;
|
float a, a0, a1, a2, b0, b1, b2, w0;
|
||||||
w0 = 2. * PI * frequency / SAMPLING_FREQUENCY_BP;
|
w0 = 2. * PI * frequency / SAMPLING_FREQUENCY_BP;
|
||||||
a = sin(w0 / (2. * Q));
|
a = sin(w0 / (2. * Q));
|
||||||
@ -135,7 +135,7 @@ void BeatDetectApp::loop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float delays = constrain(SAMPLING_FREQUENCY_BP * 0.25 / (1.75 + active * (2.4 - 1.75) / n_BP),
|
float delays = constrain(SAMPLING_FREQUENCY_BP * 0.25 / (1.75 + active * (2.5 - 1.75) / n_BP),
|
||||||
4., 6.);
|
4., 6.);
|
||||||
|
|
||||||
float delayed = 0;
|
float delayed = 0;
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#undef NUM_LEDS
|
||||||
|
#define NUM_LEDS 45
|
||||||
|
|
||||||
static unsigned long last_sample_time;
|
static unsigned long last_sample_time;
|
||||||
static unsigned long sample_counter;
|
static unsigned long sample_counter;
|
||||||
static float rms_avg;
|
static float rms_avg;
|
||||||
@ -75,11 +78,11 @@ static void hsl_to_rgb(uint32_t hue, uint32_t sat, uint32_t lum, uint8_t *r, uin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_engery(uint8_t *energy, size_t s)
|
static void update_energy(uint8_t *energy, size_t s)
|
||||||
{
|
{
|
||||||
for (int i = s; i >= 2; i--)
|
for (int i = s; i >= 2; i--)
|
||||||
{
|
{
|
||||||
energy[i] = (uint8_t)((float)(energy[i - 1] + energy[i - 2]) * 0.485f);
|
energy[i] = (uint8_t)((float)(energy[i - 1] + energy[i - 2]) * 0.45f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +123,12 @@ void FackelApp::loop()
|
|||||||
{
|
{
|
||||||
float rms = rms_pet1.update(rms_avg, 0.01f);
|
float rms = rms_pet1.update(rms_avg, 0.01f);
|
||||||
float e_f = energy_pt1.update(rms_avg, 0.01f);
|
float e_f = energy_pt1.update(rms_avg, 0.01f);
|
||||||
sprintf(string, "/*%f,%f*/", 1.3 * e_f, rms);
|
//sprintf(string, "/*%f,%f*/", 1.3 * e_f, rms);
|
||||||
Serial.println(string);
|
//Serial.println(string);
|
||||||
|
|
||||||
|
Serial.print(rms_avg);
|
||||||
|
Serial.print(",");
|
||||||
|
Serial.println(e_f);
|
||||||
|
|
||||||
if (rms > 1.15 * e_f)
|
if (rms > 1.15 * e_f)
|
||||||
{
|
{
|
||||||
@ -140,13 +147,16 @@ void FackelApp::loop()
|
|||||||
|
|
||||||
EVERY_N_MILLISECONDS(45)
|
EVERY_N_MILLISECONDS(45)
|
||||||
{
|
{
|
||||||
update_engery(energy, NUM_LEDS);
|
update_energy(energy, NUM_LEDS);
|
||||||
|
|
||||||
for (int i = 0; i < NUM_LEDS; i++)
|
for (int i = 0; i < NUM_LEDS; i++)
|
||||||
{
|
{
|
||||||
leds[i] = palette[energy[i]];
|
leds[NUM_LEDS-i-1] = palette[energy[i]];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leds[NUM_LEDS-1] = leds[NUM_LEDS-3];
|
||||||
|
leds[NUM_LEDS-2] = leds[NUM_LEDS-3];
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,195 +0,0 @@
|
|||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "app.h"
|
|
||||||
#include "biquad.h"
|
|
||||||
#include "pt1.h"
|
|
||||||
#include "zauberstab.h"
|
|
||||||
#include "fft.h"
|
|
||||||
|
|
||||||
#undef NUM_LEDS
|
|
||||||
#define NUM_LEDS 45
|
|
||||||
|
|
||||||
#define SAMPLING_FREQUENCY_BP 40 // number of energy chunks per second
|
|
||||||
#define Q 20. // quality factor of band pass filters
|
|
||||||
#define PI 3.1415926535897932384626433832795
|
|
||||||
|
|
||||||
#define N_SAMPLES 512
|
|
||||||
|
|
||||||
static const unsigned long sampling_period_bp = 1000000L / SAMPLING_FREQUENCY_BP;
|
|
||||||
static float energy = 0;
|
|
||||||
static unsigned long last_us_bp = 0L;
|
|
||||||
static unsigned long last_us_control = 0L;
|
|
||||||
|
|
||||||
static Biquad<float> bp_filter;
|
|
||||||
static Pt1<float> y_filter{1.f, 1.f};
|
|
||||||
static Pt1<float> pos_filter{1.f, 1.f};
|
|
||||||
|
|
||||||
static float yy1;
|
|
||||||
static float yy2;
|
|
||||||
static float yy3;
|
|
||||||
static float yy4;
|
|
||||||
static float yy5;
|
|
||||||
static float yy6;
|
|
||||||
static float y;
|
|
||||||
static float y_fil;
|
|
||||||
static float angle;
|
|
||||||
static float angle2;
|
|
||||||
static float pos_target = NUM_LEDS / 2;
|
|
||||||
static float pos_target_filtered = NUM_LEDS / 2;
|
|
||||||
static long initial_time;
|
|
||||||
|
|
||||||
static std::complex<float> samples[N_SAMPLES];
|
|
||||||
static std::complex<float> z[N_SAMPLES];
|
|
||||||
static uint32_t sample_counter = 0;
|
|
||||||
static unsigned long max_dt = 0;
|
|
||||||
static unsigned long last_sample = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
get_value(int pos, float pos0)
|
|
||||||
{
|
|
||||||
if (abs(pos0 - pos) > 5)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (40 - abs(pos0 - pos) * 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_filter(float frequency)
|
|
||||||
{
|
|
||||||
float a, a0, a1, a2, b0, b1, b2, w0;
|
|
||||||
w0 = 2. * PI * frequency / SAMPLING_FREQUENCY_BP;
|
|
||||||
a = sin(w0 / (2. * Q));
|
|
||||||
b0 = a;
|
|
||||||
b1 = 0.f;
|
|
||||||
b2 = -a;
|
|
||||||
a0 = 1.f + a;
|
|
||||||
a1 = -2.f * cos(w0);
|
|
||||||
a2 = 1.f - a;
|
|
||||||
bp_filter = Biquad<float>{a0, a1, a2, b0, b1, b2};
|
|
||||||
}
|
|
||||||
|
|
||||||
void FftDetectApp::init()
|
|
||||||
{
|
|
||||||
set_filter(2.0f);
|
|
||||||
initial_time = micros();
|
|
||||||
pos_target = NUM_LEDS / 2;
|
|
||||||
pos_target_filtered = NUM_LEDS / 2;
|
|
||||||
pos_filter.reset();
|
|
||||||
bp_filter.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FftDetectApp::deinit()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FftDetectApp::loop()
|
|
||||||
{
|
|
||||||
float sample = get_sample();
|
|
||||||
energy += std::abs(sample) * std::abs(sample);
|
|
||||||
|
|
||||||
if (micros() - last_us_bp > sampling_period_bp)
|
|
||||||
{
|
|
||||||
samples[sample_counter++] = energy;
|
|
||||||
|
|
||||||
last_us_bp = micros();
|
|
||||||
y = bp_filter.update(energy);
|
|
||||||
yy6 = yy5;
|
|
||||||
yy5 = yy4;
|
|
||||||
yy4 = yy3;
|
|
||||||
yy3 = yy2;
|
|
||||||
yy2 = yy1;
|
|
||||||
yy1 = y;
|
|
||||||
y_fil = y_filter.update(std::abs(y), 0.005f);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float delayed = yy5;
|
|
||||||
angle = atan2(delayed, y);
|
|
||||||
|
|
||||||
if (PI < abs(angle - angle2) && abs(angle - angle2) < 3 * PI)
|
|
||||||
{
|
|
||||||
angle2 = angle + 2 * PI;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
angle2 = angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos_target = map(angle2, -PI, 3 * PI, -0.3 * NUM_LEDS, NUM_LEDS * 1.5);
|
|
||||||
|
|
||||||
if (pos_target > pos_target_filtered)
|
|
||||||
{
|
|
||||||
pos_target_filtered = pos_filter.update(pos_target, 0.35f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos_filter.y_n1 = pos_target;
|
|
||||||
pos_target_filtered = pos_target;
|
|
||||||
}
|
|
||||||
|
|
||||||
energy = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_LEDS; i++)
|
|
||||||
{
|
|
||||||
leds[i].g = get_value(i, pos_target_filtered);
|
|
||||||
leds[i].r = get_value(i, pos_target_filtered + 2);
|
|
||||||
leds[i].b = get_value(i, pos_target_filtered - 2);
|
|
||||||
|
|
||||||
// leds[i].setRGB(brightness_red, brightness_green, brightness_blue);
|
|
||||||
// leds[i].setHSV(160, (rounds == 6) ? 0xFF : 0, brightness);
|
|
||||||
}
|
|
||||||
FastLED.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (sample_counter == N_SAMPLES)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
float samplesum = 0.f;
|
|
||||||
for (int i = 0; i < N_SAMPLES;i++)
|
|
||||||
{
|
|
||||||
samplesum = samplesum + std::abs(samples[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sampleavg = samplesum/N_SAMPLES;
|
|
||||||
|
|
||||||
for (int i = 0; i < N_SAMPLES;i++)
|
|
||||||
{
|
|
||||||
samples[i] = samples[i] - sampleavg;
|
|
||||||
}
|
|
||||||
|
|
||||||
FFT<float>::fft(samples, z, N_SAMPLES);
|
|
||||||
|
|
||||||
float max = 0.f;
|
|
||||||
int pos = -1;
|
|
||||||
for (int i = 20; i < 30; i++)
|
|
||||||
{
|
|
||||||
float v = std::abs(z[i]);
|
|
||||||
|
|
||||||
if (v > max)
|
|
||||||
{
|
|
||||||
max = v;
|
|
||||||
pos = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.println(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
float frequency = 40.f/512.f*pos;
|
|
||||||
set_filter(frequency);
|
|
||||||
sample_counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -15,16 +15,12 @@ struct FFTTestApp fft_test_app
|
|||||||
struct FackelApp fackel_app
|
struct FackelApp fackel_app
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
struct FftDetectApp fft_detect_app
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::reference_wrapper<App>> apps = {
|
std::vector<std::reference_wrapper<App>> apps = {
|
||||||
std::ref<App>(beat_detect_app),
|
std::ref<App>(beat_detect_app),
|
||||||
std::ref<App>(vu_meter_app),
|
std::ref<App>(fackel_app)
|
||||||
std::ref<App>(fft_test_app),
|
};
|
||||||
std::ref<App>(fackel_app),
|
|
||||||
std::ref<App>(fft_detect_app)};
|
|
||||||
|
|
||||||
unsigned int current_app = 0;
|
unsigned int current_app = 0;
|
||||||
unsigned int next_app;
|
unsigned int next_app;
|
||||||
|
Loading…
Reference in New Issue
Block a user