• WANTED: Happy members who like to discuss audio and other topics related to our interest. Desire to learn and share knowledge of science required as is 20 years of participation in forums (not all true). There are daily reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

Python module to manage Genelec SAM

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97
I'm working on an open source Python module genlc (Genelec Loudspeaker Control) to (automatically/manually) control Genelec SAM range of monitors/subwoofers:

https://github.com/markbergsma/genlc

So far the genlc module supports just some of the basics; discovery of all devices, wakeup & shutdown, volume setting, mute/unmute and LED on/off/colors. The binary protocol Genelec is using for GLM is proprietary, so without information available on it I've had to reverse engineer it (mostly by sniffing what GLM is sending on the wire). The Genelec GLM adapter is still required for this (it translates between USB and Genelec's serial protocol, amongst its other functions), but the software application GLM is not, at least not for the tiny subset of functionality that genlc implements.

My main use case was to integrate my Genelecs into my home automation software; I use the very popular and powerful Home Assistant open source project to automate and control everything in my home, including my home theater. Likely I will soon start work on integrating the main functionality (volume control, on/off, mute, input selection, etc...) of a HA media player with this module. I'm considering for example of making it my main (digital) volume control, which I can hook up to arbitrary virtual and physical input controls.

But this Python module could be used or extended in many different ways perhaps. Is this useful to anyone else? If so, what would you like use it for, or what functionality would you like to see added to it? Please let me know. :)

It should run on the main platforms; I've tested on MacOS and Linux, with Python 3.7+. It's very much experimental code still, and much can change in incompatible ways. I've also only tested with my Genelec SAM hardware; my pair of 8330 monitors (came with differing firmware versions interestingly) and a 7350 subwoofer. I see Genelec implementing some model-specific code so there may be surprises.
 

hege

Senior Member
Forum Donor
Joined
Dec 25, 2018
Messages
371
Likes
575
Location
Finland
Can you debug how protocol works when you set crossover frequency to a speaker? I'm curious if one could force arbitraty values there. The provided 50-100hz range in 5hz increments is a bit limiting.. but maybe the coefficients are hardcoded in speaker firmware. As well as the 48dB/oct slope..
 
OP
M

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97
Can you debug how protocol works when you set crossover frequency to a speaker? I'm curious if one could force arbitraty values there. The provided 50-100hz range in 5hz increments is a bit limiting.. but maybe the coefficients are hardcoded in speaker firmware. As well as the 48dB/oct slope..

Yes, there's a command (Genelec calls it CID_MANAGE_XO I think) that GLM sends while configuring a monitor/subwoofer with a (default) parameter value of 85, which seems to be what we need. No idea what values the monitors would accept - I can play with that some.
 
OP
M

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97
Can you debug how protocol works when you set crossover frequency to a speaker? I'm curious if one could force arbitraty values there. The provided 50-100hz range in 5hz increments is a bit limiting.. but maybe the coefficients are hardcoded in speaker firmware. As well as the 48dB/oct slope..
Yes, there's a command (Genelec calls it CID_MANAGE_XO I think) that GLM sends while configuring a monitor/subwoofer with a (default) parameter value of 85, which seems to be what we need. No idea what values the monitors would accept - I can play with that some.

This is now implemented in the code on Github. I've added a new command "bass-manage" with option --xo-freq, which takes arbitrary frequency values in Hz:

$ genlc bass-manage --xo-freq 90

I was only able to briefly test this on my Genelec SAM speakers. It seemed to work (i.e. had a clear effect on low frequencies disappearing from the output of my 8330s with increasing crossover freq settings), but I'm not sure which range of values actually got accepted by the monitors. May need actual measuring, as they don't complain but perhaps silently ignore. It may also differ per model.

I don't think the filter slope is adjustable (not in GLM either I believe?) - but I could be wrong.

Please test the code and let me know if it works for you. :)
 

hege

Senior Member
Forum Donor
Joined
Dec 25, 2018
Messages
371
Likes
575
Location
Finland
Cool, I will be testing it. Only have Windows there, but all the python libusb/hid seems to work on it too?
 
OP
M

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97

hege

Senior Member
Forum Donor
Joined
Dec 25, 2018
Messages
371
Likes
575
Location
Finland
Atleast got the command command working.

C:\Program Files\Python39>genlc --debug discover
Found USB adapter: Genelec Gnet Adapter with serial #00000000011C
DEBUG:genlc.transport:Sent: b'\x85\x01"\xc8\xee~'

Just hangs after this. Tried newest hidapi.dll and also the one that's bundled with GLMv4, no difference..
 

hege

Senior Member
Forum Donor
Joined
Dec 25, 2018
Messages
371
Likes
575
Location
Finland
Ok found a few hints..

https://github.com/arachnidlabs/mcp2210/pull/13/files
https://github.com/node-hid/node-hid/issues/187

"Now we have just discovered that on windows environments we actually need to set the first byte to 0 regardless of what is sent after. "

So adding it..

Code:
import os
....
        if os.name == 'nt':
            payload = b'\x00'+payload
        logger.debug(f"Sent: {payload}")
        self.adapter.write(payload)

Awesome!

Code:
C:\Program Files\Python39>genlc discover
Found USB adapter: Genelec Gnet Adapter with serial #00000000011C
[1] GLM Adapter
        software c-0;model-GLM Adapter;ver-1.0.15.3001;hw-0.0.0;build-2020.02.19.modif
        bar code H99999F000
        microphone serial #207xxx
[2] 1237A
        serial #1049xxx
        software ver-08 hw-0300 13:44:13_16.11.2018
        bar code 1237APM61000xxx
[3] 1237A
        serial #1049xxx
        software ver-08 hw-0300 13:44:13_16.11.2018
        bar code 1237APM61000xxx

Great tool. This will probably also help with some scripted volume control, without needing to have GLM software on.

Will test the X/O stuff..
 
Last edited:

hege

Senior Member
Forum Donor
Joined
Dec 25, 2018
Messages
371
Likes
575
Location
Finland
Setting X/O between 50-120hz seems to work. But only at 5hz increments, so it's hardcoded stuff I guess.

Trying to set nonworking frequencies just return empty or "genlc.gnet.GNetException: Response code 16" which often is seen even with correct frequencies, also some timeouts here and there. I guess needs a bit more timing and error handling if user is commanding it too fast. :D

Could have been useful if Genelec enabled 40-45hz. But atleast now with genlc can do up to 120hz...

Probably The Ones can do much higher X/O (500hz?), since it's required for W371 to work..

(near mic'd at 30cm)
genlc_xo_1237a.png



Also verified with Equalizer APO that the X/O slope matches exactly 48dB/oct Linkwitz-Riley

Code:
Filter: ON HPQ Fc 100 Hz Q 0.5412
Filter: ON HPQ Fc 100 Hz Q 1.307
Filter: ON HPQ Fc 100 Hz Q 0.5412
Filter: ON HPQ Fc 100 Hz Q 1.307
 
Last edited:

Trell

Major Contributor
Joined
May 13, 2021
Messages
1,771
Likes
1,926
Nice work done here, and I hope that @Ilkka Rissanen could be helpful with protocol details.

As part of upgrade to GLM 4.0/4.1 firmware had to be updated to support the new features, and I assume that is to support positive gain low shelves and PEQ, and quite likely other things as well. This likely would complicate the development of the Python app as one would have to check for firmware versions in the monitors/subwoofers when reverse engineering the protocol.
 
OP
M

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97
Ok found a few hints..

https://github.com/arachnidlabs/mcp2210/pull/13/files
https://github.com/node-hid/node-hid/issues/187

"Now we have just discovered that on windows environments we actually need to set the first byte to 0 regardless of what is sent after. "

So adding it..

Awesome!
Nice work figuring that one out. :) Do you want to submit a PR or shall I incorporate that code?

Great tool. This will probably also help with some scripted volume control, without needing to have GLM software on.

Yes, kind of what I started it for. Keep in mind that if you're writing e.g. a Python script, you may not want the CLI command but use the module as library directly. The cli command is there, partly as example app, partly as testing/debugging tool, and also because it's just handy to have I guess. But not what I would build automations around.
 
OP
M

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97
Setting X/O between 50-120hz seems to work. But only at 5hz increments, so it's hardcoded stuff I guess.
Too bad. I can kind of understand the limited range, but no idea why they'd want to limit to 5Hz increments.
Trying to set nonworking frequencies just return empty or "genlc.gnet.GNetException: Response code 16" which often is seen even with correct frequencies, also some timeouts here and there. I guess needs a bit more timing and error handling if user is commanding it too fast. :D
Interesting, I haven't seen any response code 16 at all so far, just the rare timeout. I wonder why.

So I'm not 100% sure what these values actually mean, I just -think- 0x7E means timeout. Do you suspect response code 16 (0x10) is
GNET_NOCANDO, e.g. for out of range values?

Could have been useful if Genelec enabled 40-45hz. But atleast now with genlc can do up to 120hz...

Probably The Ones can do much higher X/O (500hz?), since it's required for W371 to work..
Yes, although it's also possible they have an alternate set of commands for the W371 related functionality, I think I saw GLM has quite a bit of dedicated code for that.
Also verified with Equalizer APO that the X/O slope matches exactly 48dB/oct Linkwitz-Riley

Code:
Filter: ON HPQ Fc 100 Hz Q 0.5412
Filter: ON HPQ Fc 100 Hz Q 1.307
Filter: ON HPQ Fc 100 Hz Q 0.5412
Filter: ON HPQ Fc 100 Hz Q 1.307
Good to see this confimed. :) Thanks!
 
Last edited:
OP
M

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97
Nice work done here, and I hope that @Ilkka Rissanen could be helpful with protocol details.

As part of upgrade to GLM 4.0/4.1 firmware had to be updated to support the new features, and I assume that is to support positive gain low shelves and PEQ, and quite likely other things as well. This likely would complicate the development of the Python app as one would have to check for firmware versions in the monitors/subwoofers when reverse engineering the protocol.

Yes, although that could have simply meant the monitors accepting a wider (positive) range of values, and not much else.

I'm also not sure whether genlc should really go there, I think it's mainly useful for day to day operation in an integrated/automated way, like a monitor controller. For actual room correction, other acoustic settings or advanced use, especially risky stuff like writing settings or flashing firmware etc, it seems best to just use GLM.

Also, it's pretty clear that this binary protocol is very much intended to be internal-use only, i.e. in a tightly controlled environment where they develop all speakers of the protocol. There doesn't seem to be support for versioning etc, and as a whole, there is very little 2-way interaction, requiring the software (GLM) to know a lot about the capabilities of the monitors, and just overwrite/declare their state it wants to see without regard for what was previously set on the monitor. That will actually complicate some things I'm planning with genlc.

If Genelec actually wanted to offer a public API for 3rd party use (which doesn't appear to be the case), it would be far better to build that off a new API using more standard protocols and conventions, and which abstracts all this away.
 

hege

Senior Member
Forum Donor
Joined
Dec 25, 2018
Messages
371
Likes
575
Location
Finland
Nice work figuring that one out. :) Do you want to submit a PR or shall I incorporate that code?

I'm lazy gitter, probably even forgot how to PR.. feel free to implement as you see fit. :)
 

limealot

New Member
Joined
Aug 23, 2021
Messages
3
Likes
3
Location
Finland
Great tool. This will probably also help with some scripted volume control, without needing to have GLM software on.
I agree, thanks very much for this great tool! It has saved me from a world of trouble. I use the CLI on a Raspberry Pi with triggerhappy and a Flirc USB (https://flirc.tv/more/flirc-usb) to receive commands from a Logitech Harmony remote. The only thing strange is the 1 sec or so silence in audio output from the speakers (I have 2x8330A) when setting a new volume value, but perhaps that's just GLM? This is just very minor nuisance of course.
 
Last edited:
OP
M

markb

Member
Joined
Apr 29, 2021
Messages
55
Likes
97
I agree, thanks very much for this great tool! It has saved me from a world of trouble. I use the CLI on a Raspberry Pi with triggerhappy and a Flirc USB (https://flirc.tv/more/flirc-usb) to receive commands from a Logitech Harmony remote.
Nice to hear it's useful to other people. :)
The only thing strange is the 1 sec or so silence in audio output from the speakers (I have 2x8330A) when setting a new volume value, but perhaps that's just GLM? This is just very minor nuisance of course.
Yes, I noticed it as well with my 8330s! I don't believe that happens with GLM, and I haven't noticed it with my 7350 subwoofer (which I used the most for testing, as I could steal it without affecting my normal audio setup too much.) I will need to investigate a bit on what GLM does differently here. I'll look into it soon.
 

Trell

Major Contributor
Joined
May 13, 2021
Messages
1,771
Likes
1,926
Good job. Do you happen to know if using this will void your warranty
That would surprise me, but Genelec has no way to check anyway with the current protocol.
 
Top Bottom