36 #include <libusb-1.0/libusb.h> 59 std::vector<unsigned char>
intToCharArray(
int in,
const size_t bytes_per_int)
61 if (in > pow(2, bytes_per_int * 8))
63 throw std::overflow_error(
"Overflow error while converting integer " + std::to_string(in) +
" to char array of " +
64 std::to_string(bytes_per_int) +
" bytes");
66 unsigned char buffer[bytes_per_int];
67 std::vector<unsigned char> char_array;
68 for (
size_t i = 0; i < bytes_per_int; i++)
70 size_t shift = 8 * (bytes_per_int - 1 - i);
71 buffer[i] = (in >> shift) & 0xff;
72 char_array.push_back(buffer[i]);
74 std::reverse(char_array.begin(), char_array.end());
78 std::vector<std::vector<unsigned char>>
makeVideoUsbPackets(
const std::vector<std::vector<Color>>& led_array_colors)
81 std::vector<Color> all_led_colors(LEDS_PER_STRIP * NUM_STRIPS, { 0, 0, 0 });
82 for (
size_t i = 0; i < led_array_colors.size(); i++)
84 for (
size_t j = 0; j < led_array_colors[i].size(); j++)
87 all_led_colors[led_index] = led_array_colors[i][j];
90 std::vector<std::vector<unsigned char>> packets;
91 std::vector<Color> packet_leds;
94 while (all_led_colors.size() > 0)
96 std::vector<int> color_bytes;
97 std::vector<unsigned char> packet;
101 packet_leds.assign(all_led_colors.begin(), all_led_colors.end());
102 all_led_colors.erase(all_led_colors.begin(), all_led_colors.end());
106 packet_leds.assign(all_led_colors.begin(), all_led_colors.begin() +
LEDS_PER_PACKET);
107 all_led_colors.erase(all_led_colors.begin(), all_led_colors.begin() +
LEDS_PER_PACKET);
111 if (all_led_colors.size() == 0)
116 for (
size_t i = 0; i < packet_leds.size(); i++)
118 color_bytes.push_back(packet_leds[i].
r_);
119 color_bytes.push_back(packet_leds[i].
g_);
120 color_bytes.push_back(packet_leds[i].
b_);
123 if ((USB_PACKET_SIZE - 1) - color_bytes.size() > 0)
125 int j = (USB_PACKET_SIZE - 1) - color_bytes.size();
126 for (
int i = 0; i < j; i++)
128 color_bytes.push_back(0);
132 for (
size_t i = 0; i < color_bytes.size(); i++)
134 int bytes_per_int = 1;
135 std::vector<unsigned char> bufferv;
137 packet.insert(packet.end(), bufferv.begin(), bufferv.end());
141 packet.insert(packet.begin(),
static_cast<unsigned char>(control));
145 throw std::runtime_error(
"Packet size does not match the allowed USB packet size");
147 packets.push_back(packet);
153 const std::vector<int>& green_lookup_values,
154 const std::vector<int>& blue_lookup_values)
156 if (red_lookup_values.size() != LOOKUP_VALUES_PER_CHANNEL ||
159 throw std::runtime_error(
"Lookup values per channel is not correct");
161 std::vector<std::vector<unsigned char>> packets;
162 std::vector<int> remaining_lookup_values;
163 std::vector<int> packet_lookup_values;
166 remaining_lookup_values.insert(remaining_lookup_values.begin(), red_lookup_values.begin(), red_lookup_values.end());
167 remaining_lookup_values.insert(remaining_lookup_values.end(), green_lookup_values.begin(), green_lookup_values.end());
168 remaining_lookup_values.insert(remaining_lookup_values.end(), blue_lookup_values.begin(), blue_lookup_values.end());
170 while (remaining_lookup_values.size() > 0)
172 std::vector<unsigned char> packet;
176 packet_lookup_values.assign(remaining_lookup_values.begin(), remaining_lookup_values.end());
177 remaining_lookup_values.erase(remaining_lookup_values.begin(), remaining_lookup_values.end());
181 packet_lookup_values.assign(remaining_lookup_values.begin(),
183 remaining_lookup_values.erase(remaining_lookup_values.begin(),
187 if (remaining_lookup_values.size() == 0)
192 if (LOOKUP_VALUES_PER_PACKET - packet_lookup_values.size() > 0)
194 int j = LOOKUP_VALUES_PER_PACKET - packet_lookup_values.size();
195 for (
int i = 0; i < j; i++)
197 packet_lookup_values.push_back(0);
201 for (
size_t i = 0; i < packet_lookup_values.size(); i++)
203 int bytes_per_int = 2;
204 std::vector<unsigned char> bufferv;
206 packet.insert(packet.end(), bufferv.begin(), bufferv.end());
209 packet.insert(packet.begin(),
static_cast<unsigned char>(0));
210 packet.insert(packet.begin(),
static_cast<unsigned char>(control));
214 throw std::runtime_error(
"Packet size does not match the allowed USB packet size");
216 packets.push_back(packet);
228 std::vector<int> lookup_values;
229 for (
int row = 0; row < 257; row++)
231 lookup_values.push_back(std::min(0xFFFF,
int(pow(row / 256.0, 2.2) * 0x10000)));
233 return lookup_values;
std::vector< std::vector< unsigned char > > makeLookupTablePackets(const std::vector< int > &red_lookup_values, const std::vector< int > &green_lookup_values, const std::vector< int > &blue_lookup_values)
makeLookupTablePackets Create USB packets for a simple color lookup table. The entire red lookup tabl...
constexpr int LOOKUP_VALUES_PER_PACKET
Color(int r, int g, int b)
std::vector< unsigned char > intToCharArray(int in, const size_t bytes_per_int)
constexpr int LEDS_PER_PACKET
constexpr int PACKET_TYPE_LUT
constexpr int LEDS_PER_STRIP
constexpr int FINAL_PACKET_BIT
constexpr int PACKET_TYPE_VIDEO
constexpr int USB_PACKET_SIZE
std::vector< int > makeDefaultLookupTable()
makeLookupTablePackets Return lookup tables as 3 lists of lookup values - one for the red channel...
std::vector< std::vector< unsigned char > > makeVideoUsbPackets(const std::vector< std::vector< Color >> &led_array_colors)
makeVideoUsbPackets Construct the USB packets to set all LED strips to the given colors. To simplify things, we always send values for all 8 * 64 LEDs. If the physical strips are shorter, or there are less then 8 strips, the extra data doesn't do anything. If the user gives us values for less than the total number of strips, or less than the total number of LEDs in any given strip, all unspecified LEDs are left dark.
constexpr int LOOKUP_VALUES_PER_CHANNEL