format documents

Signed-off-by: Thomas Schmid <tom@lfence.de>
This commit is contained in:
Thomas 2022-06-19 13:05:58 +02:00
parent 3d13f0f49a
commit 6b60c82e3e
8 changed files with 110 additions and 80 deletions

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
template <class T> template <class T>
struct Biquad { struct Biquad
{
T b0; T b0;
T b1; T b1;
T b2; T b2;
@ -14,7 +15,8 @@ struct Biquad {
Biquad() = default; Biquad() = default;
Biquad(T a1, T a2, T b0, T b1, T b2) : b0(b0), b1(b1), b2(b2), a1(a1), a2(a2){}; Biquad(T a1, T a2, T b0, T b1, T b2) : b0(b0), b1(b1), b2(b2), a1(a1), a2(a2){};
Biquad(T a0, T a1, T a2, T b0, T b1, T b2) { Biquad(T a0, T a1, T a2, T b0, T b1, T b2)
{
this->a1 = a1 / a0; this->a1 = a1 / a0;
this->a2 = a2 / a0; this->a2 = a2 / a0;
this->b0 = b0 / a0; this->b0 = b0 / a0;
@ -22,7 +24,8 @@ struct Biquad {
this->b2 = b2 / a0; this->b2 = b2 / a0;
} }
T update(T x) { T update(T x)
{
T y = this->b0 * x + this->b1 * this->xn1 + this->b2 * this->xn2 - this->yn1 * this->a1 - this->yn2 * this->a2; T y = this->b0 * x + this->b1 * this->xn1 + this->b2 * this->xn2 - this->yn1 * this->a1 - this->yn2 * this->a2;
this->xn2 = this->xn1; this->xn2 = this->xn1;

View File

@ -1,14 +1,16 @@
#pragma once #pragma once
template <class T> template <class T>
struct DcCancelation { struct DcCancelation
{
T x_n1; T x_n1;
T y_n1; T y_n1;
T R; T R;
DcCancelation(T R) : R(R){}; DcCancelation(T R) : R(R){};
T update(T x) { T update(T x)
{
T y = x - this->x_n1 + this->R * this->y_n1; T y = x - this->x_n1 + this->R * this->y_n1;
this->x_n1 = x; this->x_n1 = x;
this->y_n1 = y; this->y_n1 = y;

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
template <class T> template <class T>
struct Pt1 { struct Pt1
{
T y_n1; T y_n1;
T K; T K;
T T1; T T1;

View File

@ -1,13 +1,16 @@
#include "zauberstab.h"
#include <algorithm> #include <algorithm>
#include "biquad.h" #include "biquad.h"
#include "pt1.h" #include "pt1.h"
#include "zauberstab.h"
#undef NUM_LEDS #undef NUM_LEDS
#define NUM_LEDS 45 #define NUM_LEDS 45
#define SAMPLING_FREQUENCY_BP 40 // number of energy chunks per second #define SAMPLING_FREQUENCY_BP 40 // number of energy chunks per second
#define SAMPLING_FREQUENCY_CONTROL 1 // check number of times per second if the current band pass is the best one #define SAMPLING_FREQUENCY_CONTROL \
1 // check number of times per second if the current band pass is the best
// one
#define Q 20. // quality factor of band pass filters #define Q 20. // quality factor of band pass filters
#define PI 3.1415926535897932384626433832795 #define PI 3.1415926535897932384626433832795
#define n_BP 30 // number of band pass filters #define n_BP 30 // number of band pass filters
@ -45,7 +48,8 @@ static int candidate = 15;
static int rounds = 0; static int rounds = 0;
static int n_samples = 0; static int n_samples = 0;
static int get_value(int pos, float pos0) static int
get_value(int pos, float pos0)
{ {
if (abs(pos0 - pos) > 5) if (abs(pos0 - pos) > 5)
{ {
@ -57,7 +61,8 @@ static int get_value(int pos, float pos0)
} }
} }
static void set_filter() static void
set_filter()
{ {
for (int i = 0; i < n_BP; i++) for (int i = 0; i < n_BP; i++)
{ {
@ -81,8 +86,8 @@ void setup()
Serial.begin(250000); Serial.begin(250000);
set_filter(); set_filter();
initial_time = micros(); initial_time = micros();
} }
void loop() void loop()
{ {
float sample = get_sample(); float sample = get_sample();
@ -104,12 +109,14 @@ void loop()
yy3[i] = yy2[i]; yy3[i] = yy2[i];
yy2[i] = yy1[i]; yy2[i] = yy1[i];
yy1[i] = y[i]; yy1[i] = y[i];
y_fil[i] = y_filter.update(std::abs(y[i]), 0.005f); //linie der scheitelpunkte y_fil[i] = y_filter.update(std::abs(y[i]),
//y_fil[i] += (abs(y[i]) - y_fil[i]) * 0.005; //linie der scheitelpunkte 0.005f); // linie der scheitelpunkte
// y_fil[i] += (abs(y[i]) - y_fil[i]) * 0.005; //linie der
// scheitelpunkte
} }
float delays = constrain(SAMPLING_FREQUENCY_BP * 0.25 / (1.75 + active * (2.4 - 1.75) / n_BP), 4., 6.); float delays = constrain(SAMPLING_FREQUENCY_BP * 0.25 / (1.75 + active * (2.4 - 1.75) / n_BP),
4., 6.);
float delayed = 0; float delayed = 0;
if (delays > 5) if (delays > 5)
@ -136,7 +143,8 @@ void loop()
if (pos_target > pos_target_filtered) if (pos_target > pos_target_filtered)
{ {
pos_target_filtered = pos_filter.update(pos_target, 0.35f); } pos_target_filtered = pos_filter.update(pos_target, 0.35f);
}
else else
{ {
pos_filter.y_n1 = pos_target; pos_filter.y_n1 = pos_target;
@ -151,7 +159,6 @@ void loop()
leds[i].r = get_value(i, pos_target_filtered + 2); leds[i].r = get_value(i, pos_target_filtered + 2);
leds[i].b = 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].setRGB(brightness_red, brightness_green, brightness_blue);
// leds[i].setHSV(160, (rounds == 6) ? 0xFF : 0, brightness); // leds[i].setHSV(160, (rounds == 6) ? 0xFF : 0, brightness);
} }

View File

@ -17,22 +17,27 @@ void fft(std::complex<float> *samples, std::complex<float> *output, uint32_t N)
{ {
uint8_t log2n = (uint8_t)std::log2(N) + 0.5f; uint8_t log2n = (uint8_t)std::log2(N) + 0.5f;
std::complex<float> I(0.0, 1.0); std::complex<float> I(0.0, 1.0);
if (N == 1) { if (N == 1)
{
output[0] = samples[0]; output[0] = samples[0];
return; return;
} }
// shuffle array // shuffle array
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++)
{
output[i] = samples[bitReverse(i, log2n)]; output[i] = samples[bitReverse(i, log2n)];
} }
for(int s = 1; s <= log2n; s++) { for (int s = 1; s <= log2n; s++)
{
uint32_t m = 1 << s; // 2^s uint32_t m = 1 << s; // 2^s
std::complex<float> wm = std::exp(-2.0f * (float)M_PI * I / (std::complex<float>)m); std::complex<float> wm = std::exp(-2.0f * (float)M_PI * I / (std::complex<float>)m);
for (int k = 0; k < N; k += m) { for (int k = 0; k < N; k += m)
{
std::complex<float> w = 1.f; std::complex<float> w = 1.f;
for (int j = 0; j < m/2; j++) { for (int j = 0; j < m / 2; j++)
{
std::complex<float> t = w * output[k + j + m / 2]; std::complex<float> t = w * output[k + j + m / 2];
std::complex<float> u = output[k + j]; std::complex<float> u = output[k + j];
output[k + j] = u + t; output[k + j] = u + t;
@ -43,20 +48,23 @@ void fft(std::complex<float> *samples, std::complex<float> *output, uint32_t N)
} }
} }
void rfft(std::complex<float> *input, std::complex<float> *output, uint32_t N){ void rfft(std::complex<float> *input, std::complex<float> *output, uint32_t N)
{
std::complex<float> I(0.0, 1.0); std::complex<float> I(0.0, 1.0);
for(int i = 0; i< N/2; i++){ for (int i = 0; i < N / 2; i++)
{
input[i] = input[i] + I * input[i + N / 2]; input[i] = input[i] + I * input[i + N / 2];
} }
fft(input, output, N / 2); fft(input, output, N / 2);
for(int i = 0; i < N/2; i++){ for (int i = 0; i < N / 2; i++)
{
output[i] = (output[i] + std::conj(output[(N / 2) - i])) / 2.f; output[i] = (output[i] + std::conj(output[(N / 2) - i])) / 2.f;
} }
for(int i = N/2; i < N; i++) { for (int i = N / 2; i < N; i++)
{
output[i] = -I * (output[i] - std::conj(output[(N / 2) - i])) / 2.f; output[i] = -I * (output[i] - std::conj(output[(N / 2) - i])) / 2.f;
} }
} }

View File

@ -5,17 +5,20 @@ DcCancelation<float> dc_blocker{0.95};
CRGB leds[NUM_LEDS]; CRGB leds[NUM_LEDS];
static int16_t mic_offset = 0; static int16_t mic_offset = 0;
static uint16_t read_mic() { static uint16_t read_mic()
{
return analogRead(MIC_PIN); return analogRead(MIC_PIN);
} }
int zauberstab_init() { int zauberstab_init()
{
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS); FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
// FastLED.setMaxPowerInVoltsAndMilliamps(5, 300); // FastLED.setMaxPowerInVoltsAndMilliamps(5, 300);
return 0; return 0;
} }
float get_sample() { float get_sample()
{
float sample = read_mic(); float sample = read_mic();
sample = dc_blocker.update(sample); sample = dc_blocker.update(sample);
return sample; return sample;

View File

@ -1,9 +1,10 @@
#include "zauberstab.h" #include "zauberstab.h"
void setup() { void setup()
{
zauberstab_init(); zauberstab_init();
} }
void loop() { void loop()
{
} }

View File

@ -1,5 +1,5 @@
#include "zauberstab.h"
#include "pt1.h" #include "pt1.h"
#include "zauberstab.h"
unsigned long last_sample_time; unsigned long last_sample_time;
static int sample_counter = 0; static int sample_counter = 0;
@ -19,8 +19,10 @@ void setup()
FastLED.setBrightness(100); FastLED.setBrightness(100);
} }
void loop() { void loop()
if (micros()-last_sample_time >= 500){ {
if (micros() - last_sample_time >= 500)
{
last_sample_time = micros(); last_sample_time = micros();
int32_t sample = get_sample(); int32_t sample = get_sample();
float in = sample * sample; float in = sample * sample;
@ -28,7 +30,8 @@ void loop() {
rms_avg += (in - rms_avg) / (sample_counter + 1); rms_avg += (in - rms_avg) / (sample_counter + 1);
} }
EVERY_N_MILLIS(10){ EVERY_N_MILLIS(10)
{
float vu = 20 * log10f(rms_avg); float vu = 20 * log10f(rms_avg);
vu_filt = vu_pt1_fast.update(vu, 0.01f); vu_filt = vu_pt1_fast.update(vu, 0.01f);
@ -39,13 +42,15 @@ void loop() {
max_led = max_led > 0xFF ? 0xFF : max_led; max_led = max_led > 0xFF ? 0xFF : max_led;
if (top_led < max_led){ if (top_led < max_led)
{
vu_pt1_slow.y_n1 = vu_filt; vu_pt1_slow.y_n1 = vu_filt;
top_led = max_led; top_led = max_led;
} }
fill_solid(leds, NUM_LEDS, CRGB::Black); fill_solid(leds, NUM_LEDS, CRGB::Black);
for(int i = 0; i < max_led; i++) { for (int i = 0; i < max_led; i++)
{
int idx = map(i, 0, NUM_LEDS, 0, 0xFF); int idx = map(i, 0, NUM_LEDS, 0, 0xFF);
leds[i] = ColorFromPalette(RainbowColors_p, idx); leds[i] = ColorFromPalette(RainbowColors_p, idx);
} }