API
#define MAX_H (360)
#define MAX_S (255)
#define MAX_V (200)
typedef struct _USER_HSV_COLOUR_{
volatile int h;
volatile int s;
volatile int v;
}HSV_COLOUR;
typedef struct _RGB_COLOUR_{
u8 b;
u8 r;
u8 g;
}RGB_COLOUR;
RGB_COLOUR hsv2rgb(HSV_COLOUR hsv);
HSV_COLOUR rgb2hsv(RGB_COLOUR rgb);
void rgb_send_cnt(u8 cnt);
void rgb_colour_only_set(RGB_COLOUR* colour, s32 number) ;
实现
double mic_db = 0;
#define PCM_SAMPLE_MAX 32767.0
#define REFERENCE_DB 1.0
double get_pcm_energ(short* pcm_data, int pcm_data_length)
{
double rms = 0.0;
for (int i = 0; i < pcm_data_length; i++) {
double sample = (double)pcm_data[i] / PCM_SAMPLE_MAX;
rms += sample * sample;
}
rms = sqrt(rms / pcm_data_length);
double mic_db = 20 * log10(rms / REFERENCE_DB);
return mic_db;
}
int pseudo_random()
{
static int seed = 0;
seed = ((seed * 214013 + 2531011) >> 16) & 0x7FFF;
return seed;
}
void mode_music_push()
{
#define SMOOTH_FACTOR 0.8
#define COLOR_CHANGE_INTERVAL 24
#define MAX_CONSECUTIVE_LIGHTUP (RGB_NUMBER - 1)
#define SUBSEQUENT_LIGHTUP_COUNT 5
static double smoothed_db = -30.0;
static int count = 0;
static unsigned short hsv_count = 0;
static int consecutive_lightup_count = 0;
static int subsequent_lightup_index = 0;
static int subsequent_lightup_cur_index = 0;
RGB_COLOUR tp;
HSV_COLOUR temp_hsv = { .h = 0, .s = MAX_S, .v = MAX_V };
smoothed_db = (SMOOTH_FACTOR * mic_db) + ((1 - SMOOTH_FACTOR) * smoothed_db);
if (smoothed_db < -30) smoothed_db = -30;
if (smoothed_db > -5) smoothed_db = -5;
int num_leds = (int)(((smoothed_db - (-30.0)) / ((-5.0) - (-30.0))) * (RGB_NUMBER - 1));
int num_leds_per_group = (num_leds + 1) / 2;
int start_index = 11;
int end_index = 12;
count++;
if (count >= COLOR_CHANGE_INTERVAL) {
srand(pseudo_random());
hsv_count = (hsv_count + 90) % 360;
count = 0;
}
if (num_leds >= MAX_CONSECUTIVE_LIGHTUP) {
consecutive_lightup_count++;
if (consecutive_lightup_count == 1) {
srand(pseudo_random());
subsequent_lightup_cur_index = rand() % 5 + 1;
subsequent_lightup_index = 0;
}
} else {
consecutive_lightup_count = 0;
subsequent_lightup_index = 0;
}
if (consecutive_lightup_count >= SUBSEQUENT_LIGHTUP_COUNT) {
num_leds_per_group = (RGB_NUMBER / 2 - 1) - subsequent_lightup_index - 1;
subsequent_lightup_index++;
if (subsequent_lightup_index > subsequent_lightup_cur_index) {
consecutive_lightup_count = 0;
subsequent_lightup_index = 0;
}
}
for (int i = 0; i < num_leds_per_group; i++) {
if (start_index - i >= 0) {
temp_hsv.h = (hsv_count + (i * 90 / num_leds_per_group)) % 360;
tp = hsv2rgb(temp_hsv);
rgb_colour_only_set(&tp, start_index - i);
}
if (end_index + i < RGB_NUMBER) {
temp_hsv.h = (hsv_count + (i * 90 / num_leds_per_group)) % 360;
tp = hsv2rgb(temp_hsv);
rgb_colour_only_set(&tp, end_index + i);
}
}
for (int i = num_leds_per_group; i <= start_index; i++) {
temp_hsv.v = 0;
tp = hsv2rgb(temp_hsv);
rgb_colour_only_set(&tp, start_index - i);
}
for (int i = end_index + num_leds_per_group; i < RGB_NUMBER; i++) {
temp_hsv.v = 0;
tp = hsv2rgb(temp_hsv);
rgb_colour_only_set(&tp, i);
}
rgb_send_cnt(1);
}