Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added json output of equalizer information of the device #358

Merged
merged 2 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ cmake-build-debug/

.vscode/*
*.code-workspace
*.cache/

.DS_Store
24 changes: 23 additions & 1 deletion src/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ typedef struct {
enum microphone_status microphone_status;
} BatteryInfo;

typedef struct {
int bands_count;
int bands_baseline;
float bands_step;
int bands_min;
int bands_max;
} EqualizerInfo;

typedef struct {
char* name;
float* values;
} EqualizerPreset;

typedef struct {
int count;
EqualizerPreset presets[];
} EqualizerPresets;

enum headsetcontrol_errors {
HSC_ERROR = -100,
HSC_READ_TIMEOUT = -101,
Expand Down Expand Up @@ -128,7 +146,7 @@ struct equalizer_settings {
/// The size of the bands array
int size;
/// The equalizer frequency bands values
float bands_values[];
float* bands_values;
};

/** @brief Defines the basic data of a device
Expand All @@ -148,6 +166,10 @@ struct device {
/// Name of device, used as information for the user
char device_name[64];

// Equalizer Infos
EqualizerInfo* equalizer;
EqualizerPresets* eqaulizer_presets;

wchar_t device_hid_vendorname[64];
wchar_t device_hid_productname[64];

Expand Down
19 changes: 18 additions & 1 deletion src/devices/headsetcontrol_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,22 @@ static struct device device_headsetcontrol_test;

#define TESTBYTES_SEND 32

static const uint16_t PRODUCT_IDS[] = { PRODUCT_TESTDEVICE };
#define EQUALIZER_BANDS_COUNT 10
#define EQUALIZER_BASELINE 0
#define EQUALIZER_STEP 0.5
#define EQUALIZER_BAND_MIN -10
#define EQUALIZER_BAND_MAX +10
#define EQUALIZER_PRESETS_COUNT 2

static const uint16_t PRODUCT_IDS[] = { PRODUCT_TESTDEVICE };
static EqualizerInfo EQUALIZER = { EQUALIZER_BANDS_COUNT, EQUALIZER_BASELINE, EQUALIZER_STEP, EQUALIZER_BAND_MIN, EQUALIZER_BAND_MAX };
static float preset_flat[EQUALIZER_BANDS_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static float preset_random[EQUALIZER_BANDS_COUNT] = { 6, -8, 1.5, 7, -1, -7.5, -9, 0, 9, 10 };
static EqualizerPresets EQUALIZER_PRESETS = {
EQUALIZER_PRESETS_COUNT,
{ { "flat", preset_flat },
{ "random", preset_random } }
};

static int headsetcontrol_test_send_sidetone(hid_device* device_handle, uint8_t num);
static BatteryInfo headsetcontrol_test_request_battery(hid_device* device_handle);
Expand Down Expand Up @@ -39,6 +54,8 @@ void headsetcontrol_test_init(struct device** device)
device_headsetcontrol_test.idVendor = VENDOR_TESTDEVICE;
device_headsetcontrol_test.idProductsSupported = PRODUCT_IDS;
device_headsetcontrol_test.numIdProducts = 1;
device_headsetcontrol_test.equalizer = &EQUALIZER;
device_headsetcontrol_test.eqaulizer_presets = &EQUALIZER_PRESETS;

strncpy(device_headsetcontrol_test.device_name, "HeadsetControl Test device", sizeof(device_headsetcontrol_test.device_name));
// normally filled by hid in main.c
Expand Down
2 changes: 2 additions & 0 deletions src/devices/steelseries_arctis_7_plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static struct device device_arctis;
#define EQUALIZER_BAND_MAX +12

static const uint16_t PRODUCT_IDS[] = { ID_ARCTIS_7_PLUS, ID_ARCTIS_7_PLUS_PS5, ID_ARCTIS_7_PLUS_XBOX, ID_ARCTIS_7_PLUS_DESTINY };
static EqualizerInfo EQUALIZER = { EQUALIZER_BANDS_SIZE, 0, 0.5, EQUALIZER_BAND_MIN, EQUALIZER_BAND_MAX };

static int arctis_7_plus_send_sidetone(hid_device* device_handle, uint8_t num);
static int arctis_7_plus_send_inactive_time(hid_device* device_handle, uint8_t num);
Expand All @@ -42,6 +43,7 @@ void arctis_7_plus_init(struct device** device)
device_arctis.idVendor = VENDOR_STEELSERIES;
device_arctis.idProductsSupported = PRODUCT_IDS;
device_arctis.numIdProducts = sizeof(PRODUCT_IDS) / sizeof(PRODUCT_IDS[0]);
device_arctis.equalizer = &EQUALIZER;

strncpy(device_arctis.device_name, "SteelSeries Arctis 7+", sizeof(device_arctis.device_name));

Expand Down
2 changes: 2 additions & 0 deletions src/devices/steelseries_arctis_nova_3.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ static struct device device_arctis;

static const uint16_t PRODUCT_IDS[] = { ID_ARCTIS_NOVA_3 };
static const uint8_t SAVE_DATA[MSG_SIZE] = { 0x06, 0x09 }; // Command to save settings to headset
static EqualizerInfo EQUALIZER = { EQUALIZER_BANDS_SIZE, 0, 0.5, EQUALIZER_BAND_MIN, EQUALIZER_BAND_MAX };

static int arctis_nova_3_send_sidetone(hid_device* device_handle, uint8_t num);
static int arctis_nova_3_send_equalizer_preset(hid_device* device_handle, uint8_t num);
Expand All @@ -29,6 +30,7 @@ void arctis_nova_3_init(struct device** device)
device_arctis.idVendor = VENDOR_STEELSERIES;
device_arctis.idProductsSupported = PRODUCT_IDS;
device_arctis.numIdProducts = sizeof(PRODUCT_IDS) / sizeof(PRODUCT_IDS[0]);
device_arctis.equalizer = &EQUALIZER;

strncpy(device_arctis.device_name, "SteelSeries Arctis Nova 3", sizeof(device_arctis.device_name));

Expand Down
80 changes: 58 additions & 22 deletions src/devices/steelseries_arctis_nova_7.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,29 @@ static struct device device_arctis;
#define HEADSET_OFFLINE 0x00
#define STATUS_BUF_SIZE 8

#define EQUALIZER_BANDS_SIZE 10
#define EQUALIZER_BASELINE 0x14
#define EQUALIZER_BAND_MIN -10
#define EQUALIZER_BAND_MAX +10

static const uint16_t PRODUCT_IDS[] = { ID_ARCTIS_NOVA_7, ID_ARCTIS_NOVA_7x, ID_ARCTIS_NOVA_7x_v2, ID_ARCTIS_NOVA_7p, ID_ARCTIS_NOVA_7_DIABLO_IV };
#define EQUALIZER_BANDS_COUNT 10
#define EQUALIZER_BASELINE 0
#define EQUALIZER_STEP 0.5
#define EQUALIZER_BAND_MIN -10
#define EQUALIZER_BAND_MAX +10
#define EQUALIZER_PRESETS_COUNT 4

static const uint16_t PRODUCT_IDS[] = { ID_ARCTIS_NOVA_7, ID_ARCTIS_NOVA_7x, ID_ARCTIS_NOVA_7x_v2, ID_ARCTIS_NOVA_7p, ID_ARCTIS_NOVA_7_DIABLO_IV };
static const uint8_t SAVE_DATA[MSG_SIZE] = { 0x06, 0x09 };

float flat[EQUALIZER_BANDS_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
float bass[EQUALIZER_BANDS_COUNT] = { 3.5, 5.5, 4, 1, -1.5, -1.5, -1, -1, -1, -1 };
float focus[EQUALIZER_BANDS_COUNT] = { -5, -3.5, -1, -3.5, -2.5, 4, 6, -3.5, 0 };
float smiley[EQUALIZER_BANDS_COUNT] = { 3, 3.5, 1.5, -1.5, -4, -4, -2.5, 1.5, 3, 4 };

static EqualizerInfo EQUALIZER = { EQUALIZER_BANDS_COUNT, EQUALIZER_BASELINE, EQUALIZER_STEP, EQUALIZER_BAND_MIN, EQUALIZER_BAND_MAX };
static EqualizerPresets EQUALIZER_PRESETS = {
EQUALIZER_PRESETS_COUNT,
{ { "flat", flat },
{ "bass", bass },
{ "focus", focus },
{ "smiley", smiley } }
};

static int arctis_nova_7_send_sidetone(hid_device* device_handle, uint8_t num);
static int arctis_nova_7_send_inactive_time(hid_device* device_handle, uint8_t num);
Expand All @@ -48,6 +65,8 @@ void arctis_nova_7_init(struct device** device)
device_arctis.idVendor = VENDOR_STEELSERIES;
device_arctis.idProductsSupported = PRODUCT_IDS;
device_arctis.numIdProducts = sizeof(PRODUCT_IDS) / sizeof(PRODUCT_IDS[0]);
device_arctis.equalizer = &EQUALIZER;
device_arctis.eqaulizer_presets = &EQUALIZER_PRESETS;

strncpy(device_arctis.device_name, "SteelSeries Arctis Nova 7", sizeof(device_arctis.device_name));

Expand Down Expand Up @@ -142,10 +161,16 @@ static BatteryInfo arctis_nova_7_request_battery(hid_device* device_handle)

int bat = data_read[2];

if (bat > BATTERY_MAX)
if (bat >= BATTERY_MAX)
info.level = 100;
else if (bat == 0x3)
info.level = 50;
else if (bat == 0x2)
info.level = 15;
else if (bat == 0x1)
info.level = 5;
else
info.level = map(bat, BATTERY_MIN, BATTERY_MAX, 0, 100);
info.level = 0;

return info;
}
Expand Down Expand Up @@ -184,35 +209,47 @@ static int arctis_nova_7_send_equalizer_preset(hid_device* device_handle, uint8_
{
// This headset supports only 4 presets:
// flat (default), bass boost, smiley, focus
struct equalizer_settings preset;
preset.size = EQUALIZER_BANDS_COUNT;

switch (num) {
case 0: {
uint8_t flat[MSG_SIZE] = { 0x0, 0x33, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x0 };
return hid_write(device_handle, flat, MSG_SIZE);
preset.bands_values = flat;
break;
// uint8_t flat[MSG_SIZE] = { 0x0, 0x33, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x0 };
// return hid_write(device_handle, flat, MSG_SIZE);
}
case 1: {
uint8_t bass[MSG_SIZE] = { 0x0, 0x33, 0x1b, 0x1f, 0x1c, 0x16, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x0 };
return hid_write(device_handle, bass, MSG_SIZE);
preset.bands_values = bass;
break;
// uint8_t bass[MSG_SIZE] = { 0x0, 0x33, 0x1b, 0x1f, 0x1c, 0x16, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x0 };
// return hid_write(device_handle, bass, MSG_SIZE);
}
case 2: {
uint8_t smiley[MSG_SIZE] = { 0x0, 0x33, 0x0a, 0x0d, 0x12, 0x0d, 0x0f, 0x1c, 0x20, 0x1b, 0x0d, 0x14, 0x0 };
return hid_write(device_handle, smiley, MSG_SIZE);
preset.bands_values = focus;
break;
// uint8_t focus[MSG_SIZE] = { 0x0, 0x33, 0x1a, 0x1b, 0x17, 0x11, 0x0c, 0x0c, 0x0f, 0x17, 0x1a, 0x1c, 0x0 };
// return hid_write(device_handle, focus, MSG_SIZE);
}
case 3: {
uint8_t focus[MSG_SIZE] = { 0x0, 0x33, 0x1a, 0x1b, 0x17, 0x11, 0x0c, 0x0c, 0x0f, 0x17, 0x1a, 0x1c, 0x0 };
return hid_write(device_handle, focus, MSG_SIZE);
preset.bands_values = smiley;
break;
// uint8_t smiley[MSG_SIZE] = { 0x0, 0x33, 0x0a, 0x0d, 0x12, 0x0d, 0x0f, 0x1c, 0x20, 0x1b, 0x0d, 0x14, 0x0 };
// return hid_write(device_handle, smiley, MSG_SIZE);
}
default: {
printf("Device only supports 0-3 range for presets.\n");
return HSC_OUT_OF_BOUNDS;
}
}

return arctis_nova_7_send_equalizer(device_handle, &preset);
}

static int arctis_nova_7_send_equalizer(hid_device* device_handle, struct equalizer_settings* settings)
{
if (settings->size != EQUALIZER_BANDS_SIZE) {
printf("Device only supports %d bands.\n", EQUALIZER_BANDS_SIZE);
if (settings->size != EQUALIZER_BANDS_COUNT) {
printf("Device only supports %d bands.\n", EQUALIZER_BANDS_COUNT);
return HSC_OUT_OF_BOUNDS;
}

Expand All @@ -224,7 +261,7 @@ static int arctis_nova_7_send_equalizer(hid_device* device_handle, struct equali
return HSC_OUT_OF_BOUNDS;
}

data[i + 2] = (uint8_t)(EQUALIZER_BASELINE + band_value);
data[i + 2] = (uint8_t)(0x14 + band_value);
}
data[settings->size + 3] = 0x0;

Expand All @@ -244,10 +281,9 @@ int arctis_nova_7_read_device_status(hid_device* device_handle, unsigned char* d

static int arctis_nova_7_bluetooth_when_powered_on(hid_device* device_handle, uint8_t num)
{
unsigned char data[MSG_SIZE] = { 0x00, 0xb2, num };
unsigned char data2[MSG_SIZE] = { 0x00, 0x09, 0 };
unsigned char data[MSG_SIZE] = { 0x00, 0xb2, num };
if (hid_write(device_handle, data, MSG_SIZE) >= 0) {
return hid_write(device_handle, data2, MSG_SIZE);
return hid_write(device_handle, SAVE_DATA, MSG_SIZE);
}
return HSC_READ_TIMEOUT;
}
Expand Down
2 changes: 2 additions & 0 deletions src/devices/steelseries_arctis_nova_pro_wireless.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ enum {
};

static const uint16_t PRODUCT_IDS[] = { ID_ARCTIS_NOVA_PRO_WIRELESS_BASE_STATION };
static EqualizerInfo EQUALIZER = { EQUALIZER_BANDS_SIZE, 0, 0.5, EQUALIZER_BAND_MIN, EQUALIZER_BAND_MAX };

static int set_sidetone(hid_device* device_handle, uint8_t num);
static BatteryInfo get_battery(hid_device* device_handle);
Expand All @@ -64,6 +65,7 @@ void arctis_nova_pro_wireless_init(struct device** device)
device_arctis.idVendor = VENDOR_STEELSERIES;
device_arctis.idProductsSupported = PRODUCT_IDS;
device_arctis.numIdProducts = sizeof(PRODUCT_IDS) / sizeof(PRODUCT_IDS[0]);
device_arctis.equalizer = &EQUALIZER;

strncpy(device_arctis.device_name, "SteelSeries Arctis Nova Pro Wireless", sizeof(device_arctis.device_name));

Expand Down
8 changes: 6 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,9 @@ int main(int argc, char* argv[])
return 1;
}

equalizer = malloc(sizeof(struct equalizer_settings) + size * sizeof(float));
equalizer->size = size;
equalizer = malloc(sizeof(struct equalizer_settings));
equalizer->size = size;
equalizer->bands_values = malloc(sizeof(float) * size);
for (int i = 0; i < size; i++) {
equalizer->bands_values[i] = read_buffer[i];
}
Expand Down Expand Up @@ -950,6 +951,9 @@ int main(int argc, char* argv[])
free(featureRequests[i].result.message);
}

if (equalizer != NULL) {
free(equalizer->bands_values);
}
free(equalizer);

terminate_hid(&device_handle, &hid_path);
Expand Down
Loading
Loading