HeadsetControl icon indicating copy to clipboard operation
HeadsetControl copied to clipboard

Support for Roccat Elo 7.1 Air?

Open Sebiann opened this issue 4 years ago • 7 comments

If it's possible, could it be added?

Sebiann avatar Jan 10 '21 14:01 Sebiann

I am interested in the Roccat Elo 7.1 Air as well. When I find the time I will have a look with Wireshark and the Roccat Windows software.

jastBytes avatar Apr 23 '21 08:04 jastBytes

I've started working on this. So far I'm able to switch the LEDs between off and white.

lukasgr90 avatar Apr 23 '21 22:04 lukasgr90

I've also reverse engineered and implemented setting the automatic standby time. But it does only seem to apply after restarting the headset. I need to further test it.

I won't implement the sidetone, since controlling this is mainly not done over the USB HID protocol. Instead the official software controls the sidetone basically by sending USB control commands (layer under HID) to the audio interfaces. The latter are used by the Linux audio drivers, which luckily already support controlling the sidetone! Thus a Linux user can do following with amixer:

  • First find out the ALSA-CARD-NUMBER, e.g. with pactl list and looking for alsa.card (better options are welcome :-) )
  • Then to switch it on/off: amixer -c <ALSA-CARD-NUMBER> cset numid=5,iface=MIXER,name='Main Configuration Playback Switch' <ON-OFF> with <ON-OFF> being one of "on" or "off"
  • To set the level: amixer -c <ALSA-CARD-NUMBER> cset numid=6,iface=MIXER,name='Main Configuration Playback Volume' <VALUE> with <VALUE> being a value between 0 (off) and 5632 (highest effect)

I partially understood how the battery levels are communicated.

  • After a restart the Headset sends the command: 0xE6 0x06 0x03 0x00 0x04 [... zeros, except 24th Byte is 37]
  • The official software sets the battery indicator to 100%
  • Then the Headset sends the command: 0xE6 0x06 0x03 0x00 0x03 [... zeros, except 24th Byte is 37]
  • The official software sets the battery indicator to 75%
  • Then Headset sends the command: 0xE6 0x06 0x03 0x00 0x02 [... zeros, except 24th Byte is 37]
  • The official software sets the battery indicator to 50% ... probably this "play" goes further, if my battery is used more. If we don't find a possibility to poll the battery state, we would need a daemon process. I'm not sure, how to fit this with HeadsetControl's design :-/.

lukasgr90 avatar Apr 24 '21 23:04 lukasgr90

... probably this "play" goes further, if my battery is used more. If we don't find a possibility to poll the battery state, we would need a daemon process. I'm not sure, how to fit this with HeadsetControl's design :-/.

That is something I thought about. And thats indeed not soo easy, but possible.

The main advantage of the design as-is is that the software is really simple and not bloated (like ckb-next).

I actually made a branch, that does that with Corsair https://github.com/Sapd/HeadsetControl/blob/Sapd/corsair-void-lightfix/src/devices/corsair_void.c#L357 Basically when one specifies the -d parameter, the program will call a _daemonize function of the implementation. However, this is not quite clean yet. e.g. the CTRL C interrupt must still be intercepted in main.c.

Also one must think about of how to pass information (e.g. change of sidetone) to the process. Which is probably the most difficult question and must be discussed beforehand.

Sapd avatar Apr 26 '21 08:04 Sapd

The main advantage of the design as-is is that the software is really simple and not bloated (like ckb-next).

I like this about HeadsetControl. It's a simple framework, which one can work with quickly (with some C knowledge). But on the other hand without daemon functionality it is not sufficient to fully support the Elo 7.1 Air, which forgets its LED state at restart and seems to push battery information at start.

Also one must think about of how to pass information (e.g. change of sidetone) to the process. Which is probably the most difficult question and must be discussed beforehand.

GRPC probably would be over-engineering. For the use cases I see, keeping things simple and portable I personally would consider POSIX message queues.

lukasgr90 avatar May 13 '21 00:05 lukasgr90

What don't you simply run the HeadsetControl binary using the commandline arguments and parsing the "condensed" text output of HeadsetControl that is activated via "-c"?

This works very well for me, e.g. https://github.com/centic9/headset-charge-indicator uses it this way and it avoids adding any of the complexity of queue/socket'/GRPC/... on both ends.

centic9 avatar May 13 '21 06:05 centic9

I like this about HeadsetControl. It's a simple framework, which one can work with quickly (with some C knowledge). But on the other hand without daemon functionality it is not sufficient to fully support the Elo 7.1 Air, which forgets its LED state at restart and seems to push battery information at start.

We could maybe keep it simple and provide daemon functionality at the same time.

In device.h we could introduce those functions, which every device which wishes to implement daemon functionality, can implement. main.c would call them, if the -d parameter was specified:

  • device_daemon_start - Called at start of program
  • device_daemon_run - Called periodically
  • device_daemon_stop - Called when main.c receives a SIGINT

When the -d parameter is specified, all other parameters are ignored (keeps software simple).

However, I would prefer that a device uses a different file for daemon functionality - as it usually comes with a lot of additonal code. Also e.g. for corsair, the daemon-code is quite different then the standard code. That would be possible by creating a devicename_daemon.c. devicename.c then simply references the daemon implementation.

Also we would provide another utility file, which hides (possibly) POSIX message queues and standardizes them.

To keep things further simple a call like that headsetcontrol -s 128 would search for an open daemon first, and send the commend to the daemon. Otherwise it will continue with the classic functionality.

Summarising, the main disadvantage would be, that we need more code. Also we would have to think if the effort would be actually worth it (do a lot of users need that functionality?).

What don't you simply run the HeadsetControl binary using the commandline arguments and parsing the "condensed" text output of HeadsetControl that is activated via "-c"?

This works very well for me, e.g. https://github.com/centic9/headset-charge-indicator uses it this way and it avoids adding any of the complexity of queue/socket'/GRPC/... on both ends.

This is not solely possible when daemon functionality is required (e.g. keeping states, or reacting to events like key presses). Then a call to headsetcontrol -c still needs to somehow communicate with the daemon. However this communication can and should be hidden.

Sapd avatar May 13 '21 08:05 Sapd

This issue is stale because it has been open 300 days with no activity. Remove stale label or comment or this will be closed in 60 days.

github-actions[bot] avatar May 05 '23 02:05 github-actions[bot]

This issue was closed because it has been stalled with no activity.

github-actions[bot] avatar Jul 04 '23 02:07 github-actions[bot]