/*---------------------------------------------------------*\ | HyperXMicrophoneController.cpp | | | | Driver for HyperX microphone | | | | Matt Silva (thesilvanator) | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-only | \*---------------------------------------------------------*/ #include #include "HyperXMicrophoneController.h" #include "StringUtils.h" using namespace std::chrono_literals; HyperXMicrophoneController::HyperXMicrophoneController(hidapi_wrapper hid_wrapper, hid_device* dev_handle, std::string path) { wrapper = hid_wrapper; dev = dev_handle; location = path; } HyperXMicrophoneController::~HyperXMicrophoneController() { lock.lock(); if(dev) { wrapper.hid_close(dev); } lock.unlock(); } std::string HyperXMicrophoneController::GetDeviceLocation() { return location; } std::string HyperXMicrophoneController::GetSerialString() { wchar_t serial_string[128]; int ret = wrapper.hid_get_serial_number_string(dev, serial_string, 128); if(ret != 0) { return(""); } return(StringUtils::wstring_to_string(serial_string)); } void HyperXMicrophoneController::SaveColors(std::vector colors, unsigned int num_frames) { unsigned int num_color_packets = 0; unsigned int frame = 0; unsigned char color[HYPERX_QUADCAST_S_PACKET_SIZE] = {0}; num_color_packets = num_frames/8; if(num_frames % 8) { num_color_packets++; } lock.lock(); /*---------------------------------------------------------*\ | Start Save Transaction | | 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | \*---------------------------------------------------------*/ SendToRegister(0x53, (uint8_t)num_color_packets, 0); while(frame < num_frames) { memset(color, 0, HYPERX_QUADCAST_S_PACKET_SIZE); unsigned int i = 0; while(i < 8 && frame < num_frames) { int index = HYPERX_QUADCAST_S_FRAME_SIZE * i; RGBColor top = colors[frame*2]; RGBColor bot = colors[frame*2 + 1]; color[index + 1] = 0x81; color[index + 2] = RGBGetRValue(top); color[index + 3] = RGBGetGValue(top); color[index + 4] = RGBGetBValue(top); color[index + 5] = 0x81; color[index + 6] = RGBGetRValue(bot); color[index + 7] = RGBGetGValue(bot); color[index + 8] = RGBGetBValue(bot); i++; frame++; } std::this_thread::sleep_for(15ms); wrapper.hid_send_feature_report(dev, color, HYPERX_QUADCAST_S_PACKET_SIZE); } /*---------------------------------------------------------*\ | Post Save Transaction | | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | \*---------------------------------------------------------*/ SendToRegister(0x02, 0, 0); /*---------------------------------------------------------*\ | Stop Save Transaction | | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | \*---------------------------------------------------------*/ SendToRegister(0x23, 1, 0); SendEOT((uint8_t)num_frames); /*---------------------------------------------------------*\ | Post Save Transaction | | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | \*---------------------------------------------------------*/ SendToRegister(0x02, 0, 0); lock.unlock(); /*---------------------------------------------------------*\ | Likes to have one temporary direct packet after the save | | for some reason | \*---------------------------------------------------------*/ SendDirect(colors); } void HyperXMicrophoneController::SendDirect(std::vector colors) { /*---------------------------------------------------------*\ | Verify colors size | \*---------------------------------------------------------*/ if(colors.size() != 2) { return; } RGBColor c1 = colors[0]; RGBColor c2 = colors[1]; uint8_t buffer[HYPERX_QUADCAST_S_PACKET_SIZE]; /*---------------------------------------------------------*\ | Colour packet | \*---------------------------------------------------------*/ memset(buffer, 0, HYPERX_QUADCAST_S_PACKET_SIZE); buffer[0x01] = 0x81; buffer[0x02] = RGBGetRValue(c1); buffer[0x03] = RGBGetGValue(c1); buffer[0x04] = RGBGetBValue(c1); buffer[0x05] = 0x81; buffer[0x06] = RGBGetRValue(c2); buffer[0x07] = RGBGetGValue(c2); buffer[0x08] = RGBGetBValue(c2); lock.lock(); wrapper.hid_send_feature_report(dev, buffer, HYPERX_QUADCAST_S_PACKET_SIZE); std::this_thread::sleep_for(15ms); SendToRegister(0xF2, 0, 1); lock.unlock(); } void HyperXMicrophoneController::SendEOT(uint8_t frame_count) { uint8_t buffer[HYPERX_QUADCAST_S_PACKET_SIZE]; memset(buffer, 0, HYPERX_QUADCAST_S_PACKET_SIZE); buffer[0x01] = 0x08; buffer[0x3C] = 0x28; buffer[0x3D] = frame_count; buffer[0x3E] = 0x00; buffer[0x3F] = 0xAA; buffer[0x40] = 0x55; wrapper.hid_send_feature_report(dev, buffer, HYPERX_QUADCAST_S_PACKET_SIZE); std::this_thread::sleep_for(15ms); } void HyperXMicrophoneController::SendToRegister(uint8_t reg, uint8_t param1, uint8_t param2) { uint8_t buffer[HYPERX_QUADCAST_S_PACKET_SIZE]; memset(buffer, 0, HYPERX_QUADCAST_S_PACKET_SIZE); buffer[0x01] = 0x04; buffer[0x02] = reg; // 0xF2 Apply, 0x53 Save buffer[0x08] = param1; buffer[0x09] = param2; wrapper.hid_send_feature_report(dev, buffer, HYPERX_QUADCAST_S_PACKET_SIZE); std::this_thread::sleep_for(15ms); }