вторник, 13 февраля 2024 г.

convert colors to midi note for midi controllers

I recently (2 years ago) designed and built a simple MIDI controller for my intercom system using an Arduino Leonardo, USB hub, sound card, microphone, and loudspeaker. It's quite basic, but it does the job! The controller also has buttons with backlighting using addressable LEDs (WS2812).


I wanted to display rainbow colors on the buttons, but couldn't find a way to implement it using MIDI note states. After some brainstorming, I came up with an idea.

Encoding Colors in MIDI:

Each button on the controller corresponds to a MIDI note with its own channel, volume (0-127), and on/off state. This information is sent over the MIDI transport. Most MIDI controllers with LED backlighting receive data (volume or state) on the same note as the button itself. While most controllers only handle binary states (on/off), I wanted to send more data to control the LED brightness and color (represented by hue, saturation, and value).

Limited to 127 states, I created an encoding/decoding table mapping colors to numbers. It's quite simple!

I based it on hue circle.





It looks like this image 





I set brightness (value+saturation) of color from 0(off) to 7 ("white"). Devided 127/7 = 18.4
Started from grayscale. 0 black, - 1-5 grayscale, 6 is white 
I decided to use 16 colors, and 8 notes reserved for other data (127 - 7(BW) - 7*16(COLORS)). 
So i have 16 color slot angles with 7 states. I choosed the hue circle to encode colors but changed it a little. I gevided hue color circle by 16 parts where value 1 is almost black color, 4 is pure color with max saturation, 7 almost white color.
So each value 7-13,14-20 etc. Descrobes the angle of color and its brightness. 0-6 is grayscale when 0 led os black(off) and 6 is white. 
On the other hand i neded to decode this values to hue angle and color brightness. And again it's simple. I just divide midi note volume by 7 and get color segment of hue if its int >0 or BW if int <0, and remainder of division responds to color brightness. Viola!

another words, shorter:
one more important thing:


in this metod you can't use (minimize) saturation while value is not 100%
at first you should start from adding value to 100% and only after add saturation.
available values for S & V is only 4 


Example:
to encode color HSV:
H: 207 degree
S: 80
V: 100
split hue circle to 16 parts (360/16=22.5*)
each angle consist of 7 values. 1-3 (for V 21%-100%. S=0%), 4 (for V =100%, S =100%), 5-7(V=100%, S=100%-21%)


lets do it!!

first start from Vm= int(V(100-1) /20)=4 it means that V is maximum
IF Vm = 0 THEN COLOR IS BLACK! and we change all results to midi note volume = 0

next Sm. invert values for our code.. 4 - int(S(80-1)/20)=1
IF Sm = 4 THEN COLOR IS WHITE! we change all results to midi note volume = 6

find Hm part = 207/22.5 = 9.2 / It means that it'll be 9th part of a circle
and color params v&s will start from:  9*7=63 
Hm=63

*BW slot contains 7 values start from 0 to 6.

So. color range will be 63-69 midi note volume.

let's define S&V in range. I'm so bored of it...



so our value will be midi note volume=Hm-1+Vm+Sm=63-1+4+1=68
DONE.
finally:
midi note volume = (int(H/22.5)*7)-1+(int(V-1)/20) + 4 - int((S-1)/20))

Remember that grayscale is in 0-6 range!

Next i use code conversion hsv ro rgb to light leds.


And let's decode color back to hsv.

We have midi note volume =  68

for all volume greather than 6 means it's not in grayscale.

H=int(68/7)*22.5=9*22.5=202 degree
V+S=68-(int(68/7)*7)-1=5
S = 100-(int((v+s)/4) * (v+s-4))*20 = 80
V= ((v+s-((int(v+s)/4)*(v+s-4))+1)*20=100

i am not accurate in math. but think you got an idea.


i made this controller and color transform works fine.
it works wit Voicemeeter+Macro buttons+midiOX.

Just like that.


Sorry, i don't have enough time to describe it more clear at the moment. I\ll try do it later. I hope.

I based my controller on this example
https://medium.com/@monkeytypewritr/building-your-own-midi-fighter-406948137f8f



convert colors to midi note for midi controllers

I recently (2 years ago) designed and built a simple MIDI controller for my intercom system using an Arduino Leonardo, USB hub, sound card, ...