a lot of new stuff
This commit is contained in:
parent
c93997776d
commit
a1033b265e
@ -21,4 +21,39 @@ biblio:
|
||||
* ws2812 with dma/smi from Jeremy P Bentham :
|
||||
* ws2812 - https://iosoft.blog/2020/09/29/raspberry-pi-multi-channel-ws2812/
|
||||
* dma - https://iosoft.blog/2020/05/25/raspberry-pi-dma-programming/
|
||||
* smi - https://iosoft.blog/2020/07/16/raspberry-pi-smi/
|
||||
* smi - https://iosoft.blog/2020/07/16/raspberry-pi-smi/
|
||||
|
||||
Raspi Config :
|
||||
|
||||
https://makersportal.com/blog/recording-stereo-audio-on-a-raspberry-pi
|
||||
https://learn.adafruit.com/adafruit-i2s-mems-microphone-breakout/raspberry-pi-wiring-test
|
||||
|
||||
sudo apt install python3-pip
|
||||
sudo pip3 install --upgrade adafruit-python-shell
|
||||
cd /tmp
|
||||
sudo wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2smic.py
|
||||
sudo python3 i2smic.py
|
||||
|
||||
# plug microphone
|
||||
sudo reboot
|
||||
arecord -l
|
||||
arecord -D plughw:1 -c1 -r 48000 -f S32_LE -t wav -V mono -v file.wav
|
||||
|
||||
# Control record volume
|
||||
cp res/.asoundrc ~/.asoundrc
|
||||
|
||||
# alsa API
|
||||
http://www.equalarea.com/paul/alsa-audio.html
|
||||
|
||||
# for project
|
||||
sudo apt install libasound2-dev wiringpi
|
||||
|
||||
# for cava
|
||||
sudo apt install libfftw3-dev libasound2-dev libtool automake
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
# Access point
|
||||
grep "Access point conf" $(find /etc -type f)
|
@ -3,7 +3,7 @@ Description=pixled
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=pixled -n 180 -d 2
|
||||
ExecStart=pixled -n 60 -d 2
|
||||
Restart=always
|
||||
User=root
|
||||
Group=root
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "rpi_midi_controller.h"
|
||||
#include "rpi_param.h"
|
||||
#include "rpi_pattern.h"
|
||||
|
||||
/***************************************************************************************************
|
||||
* Preprocessor Constants and Macros
|
||||
@ -40,7 +41,6 @@
|
||||
**************************************************************************************************/
|
||||
/* Command-line parameters */
|
||||
bool IsTestMode = false;
|
||||
int chanLedCount = 0;
|
||||
int logLevel = 2;
|
||||
|
||||
int previousMode = -1;
|
||||
@ -79,9 +79,6 @@ void log_lock_helper(bool lock, void *udata);
|
||||
|
||||
int main(int argc, char const *argv[]) {
|
||||
// setup
|
||||
parseCommandLineArgs(argc, argv);
|
||||
log_set_level(logLevel);
|
||||
|
||||
signal(SIGINT, terminate);
|
||||
|
||||
struct sched_param sp;
|
||||
@ -98,7 +95,7 @@ int main(int argc, char const *argv[]) {
|
||||
selector_setup();
|
||||
leddriver_setup();
|
||||
|
||||
// setup_cava();
|
||||
parseCommandLineArgs(argc, argv);
|
||||
|
||||
// loop
|
||||
while (1) {
|
||||
@ -149,7 +146,7 @@ void parseCommandLineArgs(int argc, char const *argv[]) {
|
||||
log_error("no numeric value");
|
||||
exit(-EXIT_FAILURE);
|
||||
} else {
|
||||
chanLedCount = atoi(argv[++args]);
|
||||
param_access->pixled.chanLedCount = atoi(argv[++args]);
|
||||
}
|
||||
break;
|
||||
case 'D': // -D: debug level
|
||||
@ -158,6 +155,7 @@ void parseCommandLineArgs(int argc, char const *argv[]) {
|
||||
exit(-EXIT_FAILURE);
|
||||
} else {
|
||||
logLevel = atoi(argv[++args]);
|
||||
log_set_level(logLevel);
|
||||
}
|
||||
break;
|
||||
case 'T': // -T: test mode
|
||||
@ -189,6 +187,7 @@ void manage_tasks(int previousMode, int currentMode) {
|
||||
artnet_stop();
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
cava_stop();
|
||||
break;
|
||||
default:
|
||||
@ -201,6 +200,7 @@ void manage_tasks(int previousMode, int currentMode) {
|
||||
artnet_start();
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
cava_start();
|
||||
break;
|
||||
default:
|
||||
@ -241,13 +241,14 @@ void execute_test_mode() {
|
||||
|
||||
static int i = 0, offset = 0;
|
||||
|
||||
for (size_t ledIndex = 0; ledIndex < chanLedCount; ++ledIndex) {
|
||||
set_color(ledIndex <= offset % chanLedCount ? on_rgbs[i] * .5 : off_rgbs, ledIndex);
|
||||
for (size_t ledIndex = 0; ledIndex < param_access->pixled.chanLedCount; ++ledIndex) {
|
||||
set_color(ledIndex <= offset % param_access->pixled.chanLedCount ? on_rgbs[i] * .5 : off_rgbs,
|
||||
ledIndex);
|
||||
}
|
||||
|
||||
leddriver_refresh();
|
||||
|
||||
if (offset < chanLedCount) {
|
||||
if (offset < param_access->pixled.chanLedCount) {
|
||||
++offset;
|
||||
} else {
|
||||
offset = 0;
|
||||
@ -267,7 +268,7 @@ void execute_artnet_mode() {
|
||||
|
||||
for (size_t ledBar = 0; ledBar < LED_NCHANS; ledBar++) {
|
||||
if (artnet_get_dmx_data(ledBar, &dmxData) == 0) {
|
||||
for (size_t i = 0; i < chanLedCount; ++i) {
|
||||
for (size_t i = 0; i < param_access->pixled.chanLedCount; ++i) {
|
||||
uint8_t *rgb = dmxData + (i * 3);
|
||||
rgb_data[i][ledBar] = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
|
||||
rgb_txdata(rgb_data[i], i);
|
||||
@ -278,17 +279,39 @@ void execute_artnet_mode() {
|
||||
leddriver_refresh();
|
||||
}
|
||||
|
||||
uint16_t static const minHue = 120 * UINT16_MAX / 360;
|
||||
uint16_t static const maxHue = 300 * UINT16_MAX / 360;
|
||||
uint16_t static const hueInterval = UINT16_MAX - (maxHue - minHue);
|
||||
|
||||
void execute_autonomous_mode() {
|
||||
int ret;
|
||||
uint16_t *buffer;
|
||||
|
||||
if ((ret = cava_get_buffer(&buffer)) == 0) {
|
||||
switch (param_access->auton.pattern) {
|
||||
case 0:
|
||||
bounce_led_and_color(buffer, CAVA_BAR_NUMBER);
|
||||
break;
|
||||
case 1:
|
||||
bounce_led(buffer, CAVA_BAR_NUMBER);
|
||||
break;
|
||||
case 2:
|
||||
bounce_led_and_travel(buffer, CAVA_BAR_NUMBER);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned baseLed[LED_NCHANS] = {0};
|
||||
|
||||
void execute_manual_mode() {
|
||||
int ret;
|
||||
uint16_t *buffer;
|
||||
|
||||
if ((ret = cava_get_buffer(&buffer)) == 0) {
|
||||
for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
|
||||
uint16_t barMax = 0;
|
||||
// uint16_t hueInterval = UINT16_MAX - (param_access->ledbar[ledBarIndex].hueInterval -
|
||||
// param_access->ledbar[ledBarIndex].hueBase);
|
||||
for (size_t cavaBar = 0; cavaBar < CAVA_BAR_NUMBER / LED_NCHANS; ++cavaBar) {
|
||||
unsigned barIndex = ledBarIndex * CAVA_BAR_NUMBER / LED_NCHANS + cavaBar;
|
||||
if (barMax < buffer[barIndex]) {
|
||||
@ -296,16 +319,17 @@ void execute_autonomous_mode() {
|
||||
}
|
||||
}
|
||||
barMax *= param_access->auton.sensitivity * param_access->ledbar[ledBarIndex].sensitivity;
|
||||
unsigned ledToLight = barMax * chanLedCount / UINT16_MAX;
|
||||
unsigned long hueShift = (long)barMax * (long)hueInterval / hueInterval;
|
||||
uint16_t hue = minHue - hueShift;
|
||||
uint32_t color = ColorHSV(hue, 255, 100);
|
||||
unsigned ledToLight = barMax * param_access->pixled.chanLedCount / 2 / UINT16_MAX;
|
||||
unsigned long hueShift =
|
||||
(long)barMax * (long)param_access->ledbar[ledBarIndex].hueInterval / UINT16_MAX;
|
||||
uint16_t hue = param_access->ledbar[ledBarIndex].hueBase - hueShift;
|
||||
uint32_t color = ColorHSV(hue, 255, param_access->ledbar[ledBarIndex].luminosity);
|
||||
|
||||
for (size_t i = 0; i < ledToLight; ++i) {
|
||||
rgb_data[i][ledBarIndex] = color;
|
||||
rgb_txdata(rgb_data[i], i);
|
||||
}
|
||||
for (size_t i = ledToLight; i < chanLedCount; ++i) {
|
||||
for (size_t i = ledToLight; i < param_access->pixled.chanLedCount; ++i) {
|
||||
rgb_data[i][ledBarIndex] = 0x000000;
|
||||
rgb_txdata(rgb_data[i], i);
|
||||
}
|
||||
@ -315,16 +339,6 @@ void execute_autonomous_mode() {
|
||||
}
|
||||
}
|
||||
|
||||
void execute_manual_mode() {
|
||||
for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
|
||||
for (size_t i = 0; i < chanLedCount; ++i) {
|
||||
rgb_data[i][ledBarIndex] = 0x000000;
|
||||
rgb_txdata(rgb_data[i], i);
|
||||
}
|
||||
}
|
||||
leddriver_refresh();
|
||||
}
|
||||
|
||||
void adjust_loop(struct timespec const *loopStart) {
|
||||
struct timespec loopEnd;
|
||||
long elapsedTimeUs, remainingTimeUs;
|
||||
|
@ -18,7 +18,8 @@
|
||||
* Preprocessor Constants and Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#define C3 0x30
|
||||
#define C3 48
|
||||
#define Gd3 56
|
||||
|
||||
/***************************************************************************************************
|
||||
* Type and Contant Definitions
|
||||
@ -161,35 +162,52 @@ void handle_in_port_events(snd_seq_event_t *ev) {
|
||||
destChannel = ev->data.control.value;
|
||||
log_info("Control param channel %d", ev->data.control.value);
|
||||
}
|
||||
} else {
|
||||
log_debug("PGMCHANGE : ch %#04x - param %u - value %d", ev->data.control.channel,
|
||||
ev->data.control.param, ev->data.control.value);
|
||||
} else if (destChannel != GLOBAL_CHANNEL) {
|
||||
log_info("Control global param");
|
||||
destChannel = GLOBAL_CHANNEL;
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_SEQ_EVENT_NOTEON:
|
||||
if (ev->data.note.note == C3) {
|
||||
if (destChannel != 0xf) {
|
||||
destChannel = 0xf;
|
||||
if (destChannel != GLOBAL_CHANNEL) {
|
||||
destChannel = GLOBAL_CHANNEL;
|
||||
log_info("Control global param");
|
||||
}
|
||||
} else if (ev->data.note.note >= Gd3) {
|
||||
set_pattern(ev->data.note.note - Gd3);
|
||||
} else {
|
||||
log_debug("NOTEON : ch %#04x - note %d - vel %d", ev->data.note.channel, ev->data.note.note,
|
||||
ev->data.note.velocity);
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_SEQ_EVENT_NOTEOFF:
|
||||
break;
|
||||
|
||||
case SND_SEQ_EVENT_CONTROLLER:
|
||||
switch (ev->data.control.param) {
|
||||
case 1:
|
||||
set_sensitivity(destChannel, ev->data.control.value + 1);
|
||||
set_sensitivity(destChannel, ev->data.control.value);
|
||||
break;
|
||||
case 2:
|
||||
set_luminosity(destChannel, ev->data.control.value);
|
||||
break;
|
||||
case 3:
|
||||
set_hue_base(destChannel, ev->data.control.value);
|
||||
break;
|
||||
case 4:
|
||||
set_hue_interval(destChannel, ev->data.control.value);
|
||||
break;
|
||||
case 5:
|
||||
set_gravity(ev->data.control.value);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_debug("CONTROLLER : ch %#04x - param %u - value %d", ev->data.control.channel,
|
||||
ev->data.control.param, ev->data.control.value);
|
||||
break;
|
||||
}
|
||||
log_debug("CONTROLLER : ch %#04x - param %u - value %d", ev->data.control.channel,
|
||||
ev->data.control.param, ev->data.control.value);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -8,8 +8,11 @@
|
||||
|
||||
#include "rpi_param.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
/***************************************************************************************************
|
||||
* Preprocessor Constants and Macros
|
||||
**************************************************************************************************/
|
||||
@ -18,9 +21,10 @@
|
||||
* Type and Contant Definitions
|
||||
**************************************************************************************************/
|
||||
|
||||
pixled_param_t const dummyPixledParam = {.intensity = .5, .hue = 0};
|
||||
auton_param_t const dummyAutonParam = {.sensitivity = 1};
|
||||
ledbar_param_t const dummyLedbarParam = {.sensitivity = 1};
|
||||
pixled_param_t const dummyPixledParam = {.chanLedCount = 0};
|
||||
auton_param_t const dummyAutonParam = {.sensitivity = 10, .gravity = 80, .pattern = 2};
|
||||
ledbar_param_t const dummyLedbarParam = {
|
||||
.sensitivity = 1., .hueBase = 121, .hueInterval = -100, .luminosity = 20, .saturation = 255};
|
||||
|
||||
/***************************************************************************************************
|
||||
* Persistent Variables
|
||||
@ -39,18 +43,74 @@ param_t param;
|
||||
void param_setup() {
|
||||
param.pixled = dummyPixledParam;
|
||||
param.auton = dummyAutonParam;
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
for (size_t i = 0; i < LED_NCHANS; ++i) {
|
||||
param.ledbar[i] = dummyLedbarParam;
|
||||
}
|
||||
param_access = ¶m;
|
||||
}
|
||||
|
||||
void set_sensitivity(int channel, unsigned int sensitivity) {
|
||||
if (channel >= 10) {
|
||||
void set_pattern(unsigned int pattern) {
|
||||
if (pattern != param.auton.pattern) {
|
||||
param.auton.pattern = pattern;
|
||||
log_debug("Pattern : %d", pattern);
|
||||
}
|
||||
}
|
||||
|
||||
void set_gravity(int8_t gravity8) {
|
||||
param.auton.gravity = gravity8 * 100 / INT8_MAX;
|
||||
log_debug("Gravity : %d", param.auton.gravity);
|
||||
}
|
||||
|
||||
void set_sensitivity(int channel, int8_t sensitivity8) {
|
||||
float sensitivity = pow(1.065, sensitivity8 - INT8_MAX / 2);
|
||||
if (channel >= LED_NCHANS) {
|
||||
param.auton.sensitivity = sensitivity;
|
||||
} else {
|
||||
param.ledbar[channel].sensitivity = sensitivity;
|
||||
}
|
||||
log_debug("Sensitivity : %f", sensitivity);
|
||||
}
|
||||
|
||||
void set_hue_base(int channel, int8_t hueBase8) {
|
||||
uint16_t hueBase = hueBase8 * HUEBASE_MAX / INT8_MAX;
|
||||
if (channel < LED_NCHANS) {
|
||||
param.ledbar[channel].hueBase = hueBase;
|
||||
} else {
|
||||
for (size_t i = 0; i < LED_NCHANS; ++i) {
|
||||
param.ledbar[i].hueBase = hueBase;
|
||||
}
|
||||
}
|
||||
log_debug("Hue base : %u", hueBase);
|
||||
}
|
||||
|
||||
void set_hue_interval(int channel, int8_t hueInterval8) {
|
||||
int16_t hueInterval = hueInterval8 - ((INT8_MAX + 1) / 2);
|
||||
if (hueInterval != 0) {
|
||||
hueInterval = hueInterval * HUEINTERVAL_MAX / (INT8_MAX / 2);
|
||||
}
|
||||
|
||||
if (channel < LED_NCHANS) {
|
||||
param.ledbar[channel].hueInterval = hueInterval;
|
||||
} else {
|
||||
for (size_t i = 0; i < LED_NCHANS; ++i) {
|
||||
param.ledbar[i].hueInterval = hueInterval;
|
||||
}
|
||||
}
|
||||
log_debug("Hue interval [%2d] : %d - [%u, %hu]", channel, hueInterval,
|
||||
param.ledbar[0].hueBase * UINT16_MAX / HUE_MAX,
|
||||
(param.ledbar[0].hueBase + hueInterval) * UINT16_MAX / HUE_MAX);
|
||||
}
|
||||
|
||||
void set_luminosity(int channel, int8_t luminosity8) {
|
||||
uint8_t luminosity = luminosity8 * UINT8_MAX / INT8_MAX;
|
||||
if (channel < LED_NCHANS) {
|
||||
param.ledbar[channel].luminosity = luminosity;
|
||||
} else {
|
||||
for (size_t i = 0; i < LED_NCHANS; ++i) {
|
||||
param.ledbar[i].luminosity = luminosity;
|
||||
}
|
||||
}
|
||||
log_debug("Luminosity : %u", luminosity);
|
||||
}
|
||||
|
||||
/***************************************************************************************************
|
||||
|
@ -18,6 +18,18 @@
|
||||
#define CHAN_MAXLEDS 6 * 60 // Maximum number of LEDs per channel
|
||||
#define LED_NCHANS 8 // Number of LED channels (8 or 16)
|
||||
|
||||
#define GLOBAL_CHANNEL 15
|
||||
|
||||
#define HUE_MAX 359
|
||||
#define HUEBASE_MIN 0
|
||||
#define HUEBASE_MAX HUE_MAX
|
||||
#define HUEINTERVAL_MIN -HUE_MAX
|
||||
#define HUEINTERVAL_MAX HUE_MAX
|
||||
#define LUMINOSITY_MIN 0
|
||||
#define LUMINOSITY_MAX 255
|
||||
#define SATURATION_MIN 0
|
||||
#define SATURATION_MAX 255
|
||||
|
||||
/***************************************************************************************************
|
||||
* Type and Contant Definitions
|
||||
**************************************************************************************************/
|
||||
@ -26,22 +38,27 @@
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t intensity;
|
||||
int hue;
|
||||
unsigned int chanLedCount;
|
||||
} pixled_param_t;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int sensitivity;
|
||||
float sensitivity;
|
||||
unsigned int gravity;
|
||||
unsigned int pattern;
|
||||
} auton_param_t;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int sensitivity;
|
||||
float sensitivity;
|
||||
unsigned int hueBase;
|
||||
int hueInterval;
|
||||
unsigned int luminosity;
|
||||
unsigned int saturation;
|
||||
} ledbar_param_t;
|
||||
|
||||
/**
|
||||
@ -50,7 +67,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
pixled_param_t pixled;
|
||||
auton_param_t auton;
|
||||
ledbar_param_t ledbar[10];
|
||||
ledbar_param_t ledbar[LED_NCHANS];
|
||||
} param_t;
|
||||
|
||||
/***************************************************************************************************
|
||||
@ -68,13 +85,33 @@ param_t *param_access;
|
||||
*/
|
||||
void param_setup();
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*
|
||||
* \param[in] pattern
|
||||
*/
|
||||
void set_pattern(unsigned int pattern);
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*
|
||||
* \param[in] pattern
|
||||
*/
|
||||
void set_gravity(int8_t gravity8);
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*
|
||||
* \param[in] channel
|
||||
*
|
||||
* \param[in] sensitivity
|
||||
* \param[in] sensitivity8
|
||||
*/
|
||||
void set_sensitivity(int channel, unsigned int sensitivity);
|
||||
void set_sensitivity(int channel, int8_t sensitivity8);
|
||||
|
||||
void set_hue_base(int channel, int8_t hueBase8);
|
||||
|
||||
void set_hue_interval(int channel, int8_t hueInterval8);
|
||||
|
||||
void set_luminosity(int channel, int8_t luminosity8);
|
||||
|
||||
#endif /* __RPI_PARAM_H__ */
|
207
RpiLedBars/src/rpi_pattern.c
Normal file
207
RpiLedBars/src/rpi_pattern.c
Normal file
@ -0,0 +1,207 @@
|
||||
/** \file .c
|
||||
* \brief This module
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* Includes
|
||||
**************************************************************************************************/
|
||||
|
||||
#include "rpi_pattern.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include "drivers/leddriver/rpi_leddriver.h"
|
||||
#include "rpi_param.h"
|
||||
|
||||
/***************************************************************************************************
|
||||
* Preprocessor Constants and Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/***************************************************************************************************
|
||||
* Type and Contant Definitions
|
||||
**************************************************************************************************/
|
||||
|
||||
/***************************************************************************************************
|
||||
* Persistent Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/**
|
||||
* RGB data buffer. Persistency is not needed but, as of it size, it must be declared in heap
|
||||
*/
|
||||
int rgbData[CHAN_MAXLEDS][LED_NCHANS];
|
||||
|
||||
/**
|
||||
* Number of led previously lighted per led bar
|
||||
*/
|
||||
int lightedLedCountArray[LED_NCHANS];
|
||||
|
||||
/**
|
||||
* Index of first previously lighted per led bar
|
||||
*/
|
||||
int baseLedIndexArray[LED_NCHANS];
|
||||
|
||||
/***************************************************************************************************
|
||||
* Internal Function Prototypes
|
||||
**************************************************************************************************/
|
||||
|
||||
uint16_t get_max_on_interval(uint16_t *array, unsigned int length, size_t intervalMin,
|
||||
size_t intervalSize);
|
||||
|
||||
uint16_t apply_sensitivity(uint16_t value, unsigned int valueIndex);
|
||||
|
||||
unsigned int get_led_to_light_count(uint16_t barValue, unsigned int barIndex);
|
||||
|
||||
unsigned int get_first_led_to_light(unsigned int barIndex);
|
||||
|
||||
/***************************************************************************************************
|
||||
* External Function Definitions
|
||||
**************************************************************************************************/
|
||||
|
||||
void bounce_led_and_color(uint16_t *spectrumArray, unsigned int spectrumLength) {
|
||||
for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
|
||||
size_t intervalSize = spectrumLength / LED_NCHANS;
|
||||
uint16_t barMax = 0;
|
||||
unsigned int ledToLightCount = 0;
|
||||
|
||||
barMax = get_max_on_interval(spectrumArray, spectrumLength, ledBarIndex * intervalSize,
|
||||
intervalSize);
|
||||
barMax = apply_sensitivity(barMax, ledBarIndex);
|
||||
ledToLightCount = get_led_to_light_count(barMax, ledBarIndex);
|
||||
|
||||
int hueShift = (long)(ledToLightCount - 1) * param_access->ledbar[ledBarIndex].hueInterval /
|
||||
(long)param_access->pixled.chanLedCount;
|
||||
uint16_t hue = param_access->ledbar[ledBarIndex].hueBase + hueShift;
|
||||
// log_trace("light %u leds on bar %u - hueShift : %d, hue %u", ledToLightCount, ledBarIndex,
|
||||
// hueShift, hue);
|
||||
uint32_t color =
|
||||
ColorHSV(hue * UINT16_MAX / HUEBASE_MAX, param_access->ledbar[ledBarIndex].saturation,
|
||||
param_access->ledbar[ledBarIndex].luminosity);
|
||||
|
||||
for (size_t i = 0; i < ledToLightCount; ++i) {
|
||||
rgbData[i][ledBarIndex] = color;
|
||||
rgb_txdata(rgbData[i], i);
|
||||
}
|
||||
for (size_t i = ledToLightCount; i < param_access->pixled.chanLedCount; ++i) {
|
||||
rgbData[i][ledBarIndex] = 0x000000;
|
||||
rgb_txdata(rgbData[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
leddriver_refresh();
|
||||
}
|
||||
|
||||
void bounce_led(uint16_t *spectrumArray, unsigned int spectrumLength) {
|
||||
for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
|
||||
size_t intervalSize = spectrumLength / LED_NCHANS;
|
||||
uint16_t barMax = 0;
|
||||
unsigned int ledToLightCount = 0;
|
||||
|
||||
barMax = get_max_on_interval(spectrumArray, spectrumLength, ledBarIndex * intervalSize,
|
||||
intervalSize);
|
||||
barMax = apply_sensitivity(barMax, ledBarIndex);
|
||||
ledToLightCount = get_led_to_light_count(barMax, ledBarIndex);
|
||||
|
||||
for (size_t i = 0; i < ledToLightCount; ++i) {
|
||||
unsigned long hueShift = (long)i * param_access->ledbar[ledBarIndex].hueInterval /
|
||||
(long)param_access->pixled.chanLedCount;
|
||||
uint16_t hue = param_access->ledbar[ledBarIndex].hueBase + hueShift;
|
||||
uint32_t color =
|
||||
ColorHSV(hue * UINT16_MAX / HUEBASE_MAX, param_access->ledbar[ledBarIndex].saturation,
|
||||
param_access->ledbar[ledBarIndex].luminosity);
|
||||
rgbData[i][ledBarIndex] = color;
|
||||
rgb_txdata(rgbData[i], i);
|
||||
}
|
||||
for (size_t i = ledToLightCount; i < param_access->pixled.chanLedCount; ++i) {
|
||||
rgbData[i][ledBarIndex] = 0x000000;
|
||||
rgb_txdata(rgbData[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
leddriver_refresh();
|
||||
}
|
||||
|
||||
void bounce_led_and_travel(uint16_t *spectrumArray, unsigned int spectrumLength) {
|
||||
for (size_t ledBarIndex = 0; ledBarIndex < LED_NCHANS; ++ledBarIndex) {
|
||||
size_t intervalSize = spectrumLength / LED_NCHANS;
|
||||
uint16_t barMax = 0;
|
||||
unsigned int ledToLightCount = 0, firstLedToLight = get_first_led_to_light(ledBarIndex);
|
||||
|
||||
barMax = get_max_on_interval(spectrumArray, spectrumLength, ledBarIndex * intervalSize,
|
||||
intervalSize);
|
||||
barMax = apply_sensitivity(barMax, ledBarIndex) / 4;
|
||||
ledToLightCount = get_led_to_light_count(barMax, ledBarIndex);
|
||||
|
||||
unsigned long hueShift = (long)(ledToLightCount - 1) * 4L *
|
||||
param_access->ledbar[ledBarIndex].hueInterval /
|
||||
(long)param_access->pixled.chanLedCount;
|
||||
uint16_t hue = param_access->ledbar[ledBarIndex].hueBase + hueShift;
|
||||
uint32_t color =
|
||||
ColorHSV(hue * UINT16_MAX / HUEBASE_MAX, param_access->ledbar[ledBarIndex].saturation,
|
||||
param_access->ledbar[ledBarIndex].luminosity);
|
||||
|
||||
for (size_t i = 0; i < ledToLightCount; ++i) {
|
||||
unsigned int ledIndex = firstLedToLight + i;
|
||||
ledIndex = ledIndex < param_access->pixled.chanLedCount
|
||||
? ledIndex
|
||||
: ledIndex - param_access->pixled.chanLedCount;
|
||||
rgbData[ledIndex][ledBarIndex] = color;
|
||||
rgb_txdata(rgbData[ledIndex], ledIndex);
|
||||
}
|
||||
for (size_t i = ledToLightCount; i < param_access->pixled.chanLedCount; ++i) {
|
||||
unsigned int ledIndex = firstLedToLight + i;
|
||||
ledIndex = ledIndex < param_access->pixled.chanLedCount
|
||||
? ledIndex
|
||||
: ledIndex - param_access->pixled.chanLedCount;
|
||||
rgbData[ledIndex][ledBarIndex] = 0x000000;
|
||||
rgb_txdata(rgbData[ledIndex], ledIndex);
|
||||
}
|
||||
}
|
||||
|
||||
leddriver_refresh();
|
||||
}
|
||||
|
||||
/***************************************************************************************************
|
||||
* Internal Function Definitions
|
||||
**************************************************************************************************/
|
||||
|
||||
uint16_t get_max_on_interval(uint16_t *array, unsigned int length, size_t intervalMin,
|
||||
size_t intervalSize) {
|
||||
uint16_t barMax = 0;
|
||||
for (size_t i = 0; i < intervalSize; ++i) {
|
||||
unsigned barIndex = intervalMin + i;
|
||||
if (barMax < array[barIndex]) {
|
||||
barMax = array[barIndex];
|
||||
}
|
||||
}
|
||||
return barMax;
|
||||
}
|
||||
|
||||
uint16_t apply_sensitivity(uint16_t value, unsigned int valueIndex) {
|
||||
return value * param_access->auton.sensitivity * param_access->ledbar[valueIndex].sensitivity;
|
||||
}
|
||||
|
||||
unsigned int get_led_to_light_count(uint16_t barValue, unsigned int barIndex) {
|
||||
unsigned int nbLightedLed = lightedLedCountArray[barIndex];
|
||||
unsigned int ledToLightCount = barValue * param_access->pixled.chanLedCount / UINT16_MAX;
|
||||
|
||||
if (ledToLightCount < nbLightedLed) {
|
||||
/* apply gravity */
|
||||
ledToLightCount = ((ledToLightCount * (100 - param_access->auton.gravity)) +
|
||||
(nbLightedLed * param_access->auton.gravity)) /
|
||||
100;
|
||||
}
|
||||
lightedLedCountArray[barIndex] = ledToLightCount;
|
||||
return ledToLightCount;
|
||||
}
|
||||
|
||||
unsigned int get_first_led_to_light(unsigned int barIndex) {
|
||||
unsigned int firstLed = baseLedIndexArray[barIndex];
|
||||
if (lightedLedCountArray[barIndex] != 0) {
|
||||
firstLed += lightedLedCountArray[barIndex] / 4 + 1;
|
||||
firstLed = firstLed < param_access->pixled.chanLedCount
|
||||
? firstLed
|
||||
: firstLed - param_access->pixled.chanLedCount;
|
||||
}
|
||||
baseLedIndexArray[barIndex] = firstLed;
|
||||
return firstLed;
|
||||
}
|
57
RpiLedBars/src/rpi_pattern.h
Normal file
57
RpiLedBars/src/rpi_pattern.h
Normal file
@ -0,0 +1,57 @@
|
||||
/** \file .h
|
||||
* \brief This module
|
||||
*/
|
||||
|
||||
#if !defined(__RPI_PATTERN_H__)
|
||||
#define __RPI_PATTERN_H__
|
||||
|
||||
/***************************************************************************************************
|
||||
* Includes
|
||||
**************************************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/***************************************************************************************************
|
||||
* Preprocessor Constants and Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/***************************************************************************************************
|
||||
* Type and Contant Definitions
|
||||
**************************************************************************************************/
|
||||
|
||||
/***************************************************************************************************
|
||||
* Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/***************************************************************************************************
|
||||
* External Function Prototypes
|
||||
**************************************************************************************************/
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*
|
||||
* \param[in] spectrumArray array of value from spectral analysis
|
||||
*
|
||||
* \param[in] spectrumLength length of spectrum array
|
||||
*/
|
||||
void bounce_led_and_color(uint16_t *spectrumArray, unsigned int spectrumLength);
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*
|
||||
* \param[in] spectrumArray array of value from spectral analysis
|
||||
*
|
||||
* \param[in] spectrumLength length of spectrum array
|
||||
*/
|
||||
void bounce_led(uint16_t *spectrumArray, unsigned int spectrumLength);
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*
|
||||
* \param[in] spectrumArray array of value from spectral analysis
|
||||
*
|
||||
* \param[in] spectrumLength length of spectrum array
|
||||
*/
|
||||
void bounce_led_and_travel(uint16_t *spectrumArray, unsigned int spectrumLength);
|
||||
|
||||
#endif /* __RPI_PATTERN_H__ */
|
Loading…
Reference in New Issue
Block a user