DIGILIGHT
picasso.c
См. документацию.
1 
13 #include <avr/io.h>
14 #include "../avr_helper.h"
15 #include <stdlib.h>
16 #include <string.h>
17 #include <avr/eeprom.h>
18 #include "../color_transform.h"
19 #include "../global.h"
20 #include "../pixel.h"
21 #include "../main_effect.h"
25 static void _effect(signal_t *s);
26 static void _stop(void);
27 static void _start(void);
28 static preset_result_t _preset(int8_t d);
29 static void _save(void);
30 
31 // Название эффекта, не более 16 знаков
32 static __flash const char _name[] = "PICASSO";
33 // Описание эффекта. Можно не менять, можно для оптимизации заменить
34 // отсутствующие функции на NULL
35 static flash_effect_t effect_def = {
36  .name = _name,
37  .work = _effect // это значение не может быть NULL!
38 };
39 
40 INIT(7){
41  // регистрация эффекта - правильно указать тип эффекта!
42  register_effect(FOREGROUND_EFFECT, &effect_def);
43 }
44 
45 #define PIC_SZ 4
46 #define DELTA_LIMIT 500
47 #define HARM 4
48 
49 // массив номеров полос анализа
50 static __flash const uint8_t harm[HARM] = {
51  //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
52  3, 7, 10, 15
53 };
54 
55 static uint8_t DIV = 1;
56 static int8_t offset;
57 
58 typedef struct{
59  uint8_t predelay;
60  uint16_t peak;
61  uint8_t picture[PIC_SZ];
62 } delta_t;
63 
64 static delta_t delta[HARM];
65 
66 uint16_t rand_range(uint16_t range){
67  return rand() % range;
68 }
69 
70 uint16_t rand_deviation(uint16_t center, uint16_t dev_width){
71  return center + dev_width / 2 - rand_range(dev_width);
72 }
73 
74 static void local_fade(uint8_t f){
75  for(uint8_t j=0; j<PIC_SZ; j++){
76  // ждем, пока истечет время ожидания
77  if(delta[f].predelay)
78  delta[f].predelay--;
79  else {
80  // после чего быстро уменьшаем яркость
81  // TODO спад яркости после выжидания
82  if(pixels[delta[f].picture[j]].delta == 1){
83  pixels[delta[f].picture[j]].bright /= 2;
84  pixels[delta[f].picture[j]].delta = 50;
85  }
86  // и порог
87  if(delta[f].peak >= 0) delta[f].peak -= 50;
88  }
89  }
90 }
91 
92 static void make_picture(uint8_t f, uint16_t peak){
93  uint8_t k = PIC_SZ;
94  hsv_t color = {330,255,255};
95 
96  // очищаем рисунок
97  memset(delta[f].picture, 0, PIC_SZ);
98 
99  while(peak && k){
100  // выбираем случайный пиксел, тяготеющий к пропорциональной частоте позиции на линейке
101  delta[f].picture[k-1] = rand_deviation(f*(PIXEL_CNT/HARM), 10) % PIXEL_CNT;
102  // сразу ему задаем яркость и дельту
103  pixels[delta[f].picture[k-1]].bright = 255;
104  pixels[delta[f].picture[k-1]].delta = 1;
105  // и назначаем цвет пропорционально частоте
106  color.h = (HSV_GRADE / HARM) * f;
107  set_hsv_color(delta[f].picture[k-1], color);
108  k--;
109  peak /= 2;
110  }
111 }
112 
113 static void paint2(signal_t *s){
114  static uint8_t wait[32];
115 
116  for(uint8_t i=0; i<PIXEL_CNT; i++){
117  if(wait[i])
118  wait[i]--;
119  else {
120  pixels[i].delta = 25;
121  }
122  }
123  uint16_t peak = 0;
124  uint16_t p1;
125  uint8_t peak_f;
126 
127  // перебираем все частоты
128  for(uint8_t f=1; f < F_CNT; f++){
129  // выбираем наибольшую амплитуду
130  p1 = (s->harmonics[f] / (1+3/f));
131  if(p1 > peak){
132  peak = p1;
133  peak_f = f;
134  }
135  }
136  // только для частоты с наибольшей амплитудой
137  if((peak >> 2) > 80) {
138  wait[peak_f] = 40;
139  hsv_t color = {330,255,255};
140  color.h = offset+(HSV_GRADE / HARM) * (peak_f-1);
141  uint8_t pix = rand_range(PIXEL_CNT);
142  set_hsv_color(pix, color);
143  bright_ctrl(pix, 255, 1);
144  }
145 }
146 
147 // главная функция эффекта - вызывается 100 раз в секунду для рендеринга
148 static void _effect(signal_t *s){
149  static uint8_t div = 1;
150 
151 
152  if(--div) return;
153  div = DIV;
154 
155  paint2(s);
156 }
157 
158 
void bright_ctrl(uint8_t id, uint8_t bright, int8_t delta)
Управление яркостью
Definition: pixel.c:95
int8_t delta
условная скорость автоматического изменения яркости
Definition: pixel.h:38
const __flash effect_t flash_effect_t
тип описания эффекта, размещенного во FLASH.
Definition: main_effect.h:79
структура параметров звукового сигнала
Definition: global.h:72
uint16_t h
Оттенок цвета, значения в градусах 0...359.
uint16_t harmonics[F_CNT]
амплитуды всех гармоник сигнала
Definition: global.h:77
preset_result_t
результат функции смены пресета
Definition: main_effect.h:56
#define PIXEL_CNT
Общее количество пикселов
Definition: pixel.h:27
Тип для представления цвета в HSV-модели
#define FOREGROUND_EFFECT
основной эффект
Definition: main_effect.h:50
Общее количество гармоник
Definition: global.h:44
pixel_t pixels[MAX_TOTAL_PIX]
Массив пикселей предельного размера
Definition: pixel.c:22
void register_effect(uint8_t toe, flash_effect_t *eff)
Регистрация эффекта в списках
Definition: main_effect.c:41
uint8_t bright
яркость пиксела
Definition: pixel.h:37