Open askruga opened 2 years ago
first I want to start off with letting you know that the code works with python 2.7 only. I stumbled across some kind of a hole where I am able to get notifications when other applications start and stop playing. This is not something that is supposed to happen and every time I port he code to python 3 that feature stops functioning.
First I have to explain the structure to you so you understand how things are put together.
You have a device and that device has endpoints. This is where it can get a bit confusing. An endpoint is either an input or an output, i can be a single jack or it can be multiple jacks or it might not be a jack at all (i know right).
so when you open up your sound manager in windows you see things like headphones, speakers, spdif those kinds of things. Those would be endpoints.
You need to know if you want to change the volume level on a global level or do you want to change the volume for only the headphones or the speakers.
Switch default device, i mean "Speakers" to "Headphones" and how i can get event callbacks for it?
yes
Can i switch Channel Volume Level? I mean change volume level just for "Chrome.exe" or "Skype.exe"
no, application controls are called "sessions" and only the owning process of that session (or windows sound manager) is able to do that. could you imagine what it would be like if one application could change another applications sound settings. Microsoft did not release the API for changing the default sound device for this same reason. At some point some developer for Microsoft did leak that API to the public and that is the reason why we are able to do it.
We are able to get events when a session starts and stops playing, this is not something that is supposed to happen but for some reason it does.
but in pypi.org i found this lib for python 3.7-3.9 and without descriprion and other links and by other author.
TY for letting me know this, I am going to have pypi pull it down as there is no credit given to me and I am the original author. And to make matters worse, it is an improper conversion and it is going to have issues. The Windows data types are not properly set up for a 64bit python for starters, they didn't change the singleton metaclass to work properly with Python 3 and there are other things as well.
It looks like the person that made the change did update the code in attempt to be able to change session volumes of other applications but that is only going to work if the session events continue to work and every time I have made the conversion they stop functioning. I was never able to set the session volume levels so the code they added might not work.
Mostly what the person that added that to pypi did was change the print statements and change the import statements. I personally find it exceedingly rude that the person did not ask if they could post it on pypi and that they provide no link on how to get support for their modified version.
give me a day to hammer out an example for you an I will once again screw with getting it ported to Python 3.
@kdschlosser Thanks for you answer. Some thing become more understundable for me. Look forward to some examples. And adaptation for py3 ofcourse.
Can i switch Channel Volume Level? I mean change volume level just for "Chrome.exe" or "Skype.exe"
Sorry. Ofc i mean sessions. But I did not understand your answer unequivocally. In sum we can't did it?
You need to know if you want to change the volume level on a global level or do you want to change the volume for only the headphones or the speakers.
Global level - its master volume for all or separately sessions. Did I understand correctly?
P.S. I hope you are not very upset about the situation with pypi.
It's cool about the pypi thing. It has been removed. My gripe with it was mostly the fact that the person did not provide information on where to get support for their version. It also appears that the name of the author is not who made the modifications. the name of the author is a female and the person that did the work is a guy.. kinds strange deal if you ask me.
I am working on the python 3 port of it, we will see how it goes. I am writing a lot of it over again as my knowledge on how to write bindings to the windows API has improved since I wrote this library. IDK if you looked at pyWinAPI at all but it includes about 1,000,000 lines of code. Its not something that run it is used to save time. It is a direct port of the windows 10 SDK. or 1,000,000 lines of the 6,000,000 in the SDK.
OK wanted to let you know that I didn't leave you hangin. I am working on the Python 3 port and it is coming along pretty good.
I am writing about 80% of the thing over. I want to expose more of the low level bits to the users. The Python 2.7 version also had a wicked memory leak in it that I never managed to locate. It also had an issue with unicode characters (non English languages) I am hoping that these are sorted out now.
I have to test the sessions and getting notifications when different things change, like new sessions getting started and new devices being added or when the volume changes. I am also going to expose some of the KS end of things to allow for altering pieces like bass boost and being able to set the channel configuration.
I still have to test the volume controls as well and I have to get the interfaces to work for AGC, Bass, Treble, Mid , etc..
Here is a test I just finish up doing. I wanted t make sure that I enumerate the devices properly and the endpoints for a device. I also made sure that the various properties and attributes of the devices and the endpoints all worked.
AMD High Definition Audio Device
endpoints:
endpoint: 1 - Digital Display Audio (AMD High Definition Audio Device)
description: 1 - Digital Display Audio
type: Hdmi Interface
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {0D6DA6D5-450F-4A1C-ACA4-6A852D535C6A}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: 1 - Digital Display Audio
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: 2 - Digital Display Audio (AMD High Definition Audio Device)
description: 2 - Digital Display Audio
type: Hdmi Interface
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {41AE340C-C4EE-44A6-A388-61BE3AA3046C}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: 2 - Digital Display Audio
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: 3 - Digital Display Audio (AMD High Definition Audio Device)
description: 3 - Digital Display Audio
type: Hdmi Interface
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {75C5782C-D301-4C4C-80CC-80EEC7E07E2C}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: 3 - Digital Display Audio
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: 5 - Digital Display Audio (AMD High Definition Audio Device)
description: 5 - Digital Display Audio
type: Hdmi Interface
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {7F5F84C4-1BC3-4616-8F44-BDBE11173E1C}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: 5 - Digital Display Audio
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: 6 - Digital Display Audio (AMD High Definition Audio Device)
description: 6 - Digital Display Audio
type: Hdmi Interface
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {B4BB93B7-BD50-40E5-B268-3DDEE272FCDF}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: 6 - Digital Display Audio
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: 4 - Digital Display Audio (AMD High Definition Audio Device)
description: 4 - Digital Display Audio
type: Hdmi Interface
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {C2828656-5AB2-4BF9-A723-622F3A3E767A}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: 4 - Digital Display Audio
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: Internal AUX Jack (AMD High Definition Audio Device)
description: Internal AUX Jack
type: Unknown
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {1521C3EA-9909-4CD6-A11C-F1076AEBC405}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name:
connector_subtype:
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: Internal AUX Jack (AMD High Definition Audio Device)
description: Internal AUX Jack
type: Unknown
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {1E069735-CD50-4328-BE32-E5A93CAA2075}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name:
connector_subtype:
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: Internal AUX Jack (AMD High Definition Audio Device)
description: Internal AUX Jack
type: Unknown
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {725CD6F0-C930-4613-830D-74143ED2F85E}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name:
connector_subtype:
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: Internal AUX Jack (AMD High Definition Audio Device)
description: Internal AUX Jack
type: Unknown
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {7321A5DB-D9C1-44C5-A593-2A36C932D7C0}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name:
connector_subtype:
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: Internal AUX Jack (AMD High Definition Audio Device)
description: Internal AUX Jack
type: Unknown
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {AF31A520-3C90-48C4-B67B-82BF42001B0E}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name:
connector_subtype:
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
endpoint: Internal AUX Jack (AMD High Definition Audio Device)
description: Internal AUX Jack
type: Unknown
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {CC532439-97B7-467F-9E7F-31DBF5553779}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name:
connector_subtype:
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: None
connectors:
name:
data flow: In
type: Physical Internal
connected: True
connector type: Connector
connector sub type:
name: 1 - Digital Display Audio
data flow: Out
type: Physical Internal
connected: True
connector type: Connector
connector sub type: HDMI Interface
subunits:
name: Master Mute
type: Subunit
sub type: Mute
Realtek High Definition Audio
endpoints:
endpoint: Speakers (Realtek High Definition Audio)
description: Speakers
type: Speaker
data flow: Render
form_factor: Speakers
full_range_speakers: 0
guid: {2AA36ADF-25F2-4B1E-8C43-D15D464FF44E}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Realtek HDA Primary output
connector_subtype: Speaker
connector_location: On primary chassis, Rear-mounted panel
connector_style: 1/8"
presence_detection: True
connector_color: (0, 255, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 66.89499616622925
endpoint: Realtek Digital Output (Realtek High Definition Audio)
description: Realtek Digital Output
type: Spdif Interface
data flow: Render
form_factor: SPDIF
full_range_speakers: 0
guid: {44993944-1A71-45E5-960F-00B90D134431}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Realtek Digital Output
connector_subtype: SPDIF Interface
connector_location: On primary chassis, ATAPI
connector_style: ATAPI Internal
presence_detection: False
connector_color: (0, 0, 0, 255)
is_connected: True
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 42.9999977350235
endpoint: Realtek Digital Output(Optical) (Realtek High Definition Audio)
description: Realtek Digital Output(Optical)
type: Spdif Interface
data flow: Render
form_factor: SPDIF
full_range_speakers: 0
guid: {633AADA6-C313-4300-9315-0393D2FAFC93}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Realtek Digital Output(Optical)
connector_subtype: SPDIF Interface
connector_location: On primary chassis, Rear-mounted panel
connector_style: Optical
presence_detection: False
connector_color: (255, 128, 0, 255)
is_connected: True
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Realtek HD Audio 2nd output (Realtek High Definition Audio)
description: Realtek HD Audio 2nd output
type: Headphones
data flow: Render
form_factor: Headphones
full_range_speakers: 0
guid: {B7A2A829-AFAC-4CB9-B6B8-17ABC6F75925}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Realtek HD Audio 2nd output
connector_subtype: Headphones
connector_location: On primary chassis, Front-mounted panel
connector_style: 1/8"
presence_detection: True
connector_color: (0, 255, 0, 255)
is_connected: True
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 87.00000047683716
endpoint: Mic in at front panel (Pink) (Realtek High Definition Audio)
description: Mic in at front panel (Pink)
type: Microphone
data flow: Capture
form_factor: Microphone
full_range_speakers: 0
guid: {0D69CB84-3520-4D0A-A5D0-A1D901FF09D2}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Mic in at front panel (Pink)
connector_subtype: Microphone
connector_location: On primary chassis, Front-mounted panel
connector_style: 1/8"
presence_detection: True
connector_color: (255, 128, 192, 255)
is_connected: True
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 6.769580394029617
endpoint: Line In (Realtek High Definition Audio)
description: Line In
type: Line Connector
data flow: Capture
form_factor: Line Level
full_range_speakers: 0
guid: {22F7266B-FFC0-4653-A165-76DCDF8359D1}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Line In
connector_subtype: Line Connector
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Subwoofer (Realtek High Definition Audio)
description: Subwoofer
type: Analog Connector
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {3447F788-A092-4A04-9C67-B294068EB874}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: Subwoofer
connector_subtype: Analog Connector
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Center (Realtek High Definition Audio)
description: Center
type: Analog Connector
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {371BF61D-28E3-4F6A-8A59-B36E1D9E3C55}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: Center
connector_subtype: Analog Connector
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Microphone (Realtek High Definition Audio)
description: Microphone
type: Microphone
data flow: Capture
form_factor: Microphone
full_range_speakers: 0
guid: {4AD4464D-204C-4C6F-AAEA-6C1E159E54C6}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Microphone
connector_subtype: Microphone
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Line in at rear panel (Blue) (Realtek High Definition Audio)
description: Line in at rear panel (Blue)
type: Line Connector
data flow: Capture
form_factor: Line Level
full_range_speakers: 0
guid: {4DC4A388-4F21-4B8E-9789-A061E95181BA}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Line in at rear panel (Blue)
connector_subtype: Line Connector
connector_location: On primary chassis, Rear-mounted panel
connector_style: 1/8"
presence_detection: True
connector_color: (0, 0, 255, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 22.01419025659561
endpoint: Front Pink In (Realtek High Definition Audio)
description: Front Pink In
type: Analog Connector
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {5B997D39-E938-4DE2-A432-CC8A4028D153}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: Front Pink In
connector_subtype: Analog Connector
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (255, 128, 192, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Line in at front panel (Green) (Realtek High Definition Audio)
description: Line in at front panel (Green)
type: Line Connector
data flow: Capture
form_factor: Line Level
full_range_speakers: 0
guid: {7D9EE5B7-134F-4B04-B15D-181C8C10C2E1}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Line in at front panel (Green)
connector_subtype: Line Connector
connector_location: On primary chassis, Front-mounted panel
connector_style: 1/8"
presence_detection: True
connector_color: (0, 255, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 22.01419025659561
endpoint: Mic in at rear panel (Pink) (Realtek High Definition Audio)
description: Mic in at rear panel (Pink)
type: Microphone
data flow: Capture
form_factor: Microphone
full_range_speakers: 0
guid: {A59B0AAB-CEA8-4FFF-B1B6-C62666202850}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Mic in at rear panel (Pink)
connector_subtype: Microphone
connector_location: On primary chassis, Rear-mounted panel
connector_style: 1/8"
presence_detection: True
connector_color: (255, 128, 192, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 6.769580394029617
endpoint: Front Green In (Realtek High Definition Audio)
description: Front Green In
type: Analog Connector
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {AFE8A438-E24E-45D9-8CDE-C3B459E6CC5A}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: Front Green In
connector_subtype: Analog Connector
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 255, 0, 255)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Rear (Realtek High Definition Audio)
description: Rear
type: Analog Connector
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {BB68BA88-2E93-4867-AB8B-8C69AD036E7D}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: Rear
connector_subtype: Analog Connector
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Front (Realtek High Definition Audio)
description: Front
type: Analog Connector
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {D121F5F6-DA5C-4D78-9FF0-BDA29FFD9280}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: Front
connector_subtype: Analog Connector
connector_location: Unknown
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 0)
is_connected: False
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 100.0
endpoint: Stereo Mix (Realtek High Definition Audio)
description: Stereo Mix
type: Analog Connector
data flow: Capture
form_factor: Unknown
full_range_speakers: 0
guid: {F88AEA7C-4ABC-4E08-8F78-BB22D19EB59C}
physical_speakers: 0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical Internal
connector_name: Stereo Mix
connector_subtype: Analog Connector
connector_location: On primary chassis
connector_style: Unknown
presence_detection: False
connector_color: (0, 0, 0, 255)
is_connected: True
auto_gain_control: None
bass: None
channel_config: None
input: None
loudness: None
midrange: None
output: None
treble: None
volume: 22.01419025659561
connectors:
name:
data flow: In
type: Software Fixed
connected: True
connector type: Connector
connector sub type:
name: Realtek HDA Primary output
data flow: Out
type: Physical External
connected: True
connector type: Connector
connector sub type: Speaker
name: Microphone
data flow: In
type: Physical External
connected: True
connector type: Connector
connector sub type: Microphone
name: Front Pink In
data flow: In
type: Physical Internal
connected: True
connector type: Connector
connector sub type: Analog Connector
name: Line In
data flow: In
type: Physical External
connected: True
connector type: Connector
connector sub type: Line Connector
name: Front Green In
data flow: In
type: Physical Internal
connected: True
connector type: Connector
connector sub type: Analog Connector
name: Center
data flow: In
type: Physical Internal
connected: True
connector type: Connector
connector sub type: Analog Connector
name: Subwoofer
data flow: In
type: Physical Internal
connected: True
connector type: Connector
connector sub type: Analog Connector
name: Rear
data flow: In
type: Physical Internal
connected: True
connector type: Connector
connector sub type: Analog Connector
name: Front
data flow: In
type: Physical Internal
connected: True
connector type: Connector
connector sub type: Analog Connector
subunits:
name: Speakers
type: Subunit
sub type: Volume
name: Master Mute
type: Subunit
sub type: Mute
name: Sum
type: Subunit
sub type: Sum
name: Mute
type: Subunit
sub type: Mute
name: Microphone
type: Subunit
sub type: Volume
name: Mute
type: Subunit
sub type: Mute
name: Front Pink In
type: Subunit
sub type: Volume
name: Mute
type: Subunit
sub type: Mute
name: Line In
type: Subunit
sub type: Volume
name: Mute
type: Subunit
sub type: Mute
name: Front Green In
type: Subunit
sub type: Volume
name: Center
type: Subunit
sub type: Volume
name: Subwoofer
type: Subunit
sub type: Volume
name: Rear
type: Subunit
sub type: Volume
name: Front
type: Subunit
sub type: Volume
OK sessions are working. The volume for an endpoint is working, volume for a session is working, volume for endpoint channels is working, volume for session channels is working and the peak meter for an endpoint and it's channels are working.
I have to test the notifications and get the equalizer interfaces working.
@kdschlosser So cool!! Thanks for u lib again! I've been see into your library for 2 weeks now and have some progress. Now i can take all active(i mean sate) capture and render endpoints, switch it, set volume e.c.t. And i can set volume/mute for each session :)
Thanks for you answer! I'm really looking forward to adaptation for py3
don't get too used to using the API in the python 2 version. It is going to work completely different. It will be a whole hell of a lot easier.
In the version you are using you have to jump through hoops to handle notifications. You won't have to do that anymore.
It is going to work like this.
from pyWinCoreAudio import (
IMMDeviceEnumerator,
ON_DEVICE_ADDED,
ON_DEVICE_REMOVED,
ON_ENDPOINT_VOLUME_CHANGED
)
def on_device_added(signal, device):
print('device added:', device.name)
def on_device_removed(signal, name):
print('device removed:', name)
def on_endpoint_volume_changed(signal, device, endpoint, is_muted, master_volume, channel_volumes):
print('endpoint volume changed:', device.name + '.' + endpoint.name, 'mute:', is_muted, 'volume:', master_volume)
for i, channel in enumerate(channel_volumes):
print('channel:', i, 'volume:', channel.level)
_on_device_added = ON_DEVICE_ADDED.register(on_device_added)
_on_device_removed = ON_DEVICE_REMOVED.register(on_device_removed)
device_enum = IMMDeviceEnumerator()
volume_registrations = []
# registers to get notifications from all devices and all endpoints
_on_endpoint_volume = ON_ENDPOINT_VOLUME_CHANGED.register(on_endpoint_volume_changed)
volume_registrations.append(_on_endpoint_volume)
for device in device_enum:
print(device.name)
# registers to get notifications for all endpoints for a specific device
_on_endpoint_volume = ON_ENDPOINT_VOLUME_CHANGED.register(on_endpoint_volume_changed, device=device)
volume_registrations.append(_on_endpoint_volume)
for endpoint in device:
print(' ', endpoint.name)
# registers to get notifications for a specific endpoint
_on_endpoint_volume = ON_ENDPOINT_VOLUME_CHANGED.register(on_endpoint_volume_changed, device=device, endpoint=endpoint)
volume_registrations.append(_on_endpoint_volume)
for session in endpoint:
print(' ', session.name)
You can also do a dynamic setup for getting notifications by using the callbacks.
def on_device_added(signal, device):
print('device added:', device.name)
if device.name == 'some device name':
for endpoint in device:
if endpoint.name == 'Speakers':
_on_endpoint_volume = ON_ENDPOINT_VOLUME_CHANGED.register(on_endpoint_volume_changed, device=device, endpoint=endpoint)
_on_device_added = ON_DEVICE_ADDED.register(on_device_added)
I have the convenience interfaces all done tho most audio cards will not use those interfaces. Instead they use a different mechanism that I am going to expose. The things you will be able to adjust if the device supports it is listed below.
KSPROPERTY_AUDIO_LATENCY
KSPROPERTY_AUDIO_COPY_PROTECTION
KSPROPERTY_AUDIO_CHANNEL_CONFIG
KSPROPERTY_AUDIO_VOLUMELEVEL
KSPROPERTY_AUDIO_POSITION
KSPROPERTY_AUDIO_DYNAMIC_RANGE
KSPROPERTY_AUDIO_QUALITY
KSPROPERTY_AUDIO_SAMPLING_RATE
KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE
KSPROPERTY_AUDIO_MIX_LEVEL_TABLE
KSPROPERTY_AUDIO_MIX_LEVEL_CAPS
KSPROPERTY_AUDIO_MUX_SOURCE
KSPROPERTY_AUDIO_MUTE
KSPROPERTY_AUDIO_BASS
KSPROPERTY_AUDIO_MID
KSPROPERTY_AUDIO_TREBLE
KSPROPERTY_AUDIO_BASS_BOOST
KSPROPERTY_AUDIO_EQ_LEVEL
KSPROPERTY_AUDIO_NUM_EQ_BANDS
KSPROPERTY_AUDIO_EQ_BANDS
KSPROPERTY_AUDIO_AGC
KSPROPERTY_AUDIO_DELAY
KSPROPERTY_AUDIO_LOUDNESS
KSPROPERTY_AUDIO_WIDE_MODE
KSPROPERTY_AUDIO_WIDENESS
KSPROPERTY_AUDIO_REVERB_LEVEL
KSPROPERTY_AUDIO_CHORUS_LEVEL
KSPROPERTY_AUDIO_DEV_SPECIFIC
KSPROPERTY_AUDIO_DEMUX_DEST
KSPROPERTY_AUDIO_STEREO_ENHANCE
KSPROPERTY_AUDIO_MANUFACTURE_GUID
KSPROPERTY_AUDIO_PRODUCT_GUID
KSPROPERTY_AUDIO_CPU_RESOURCES
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY
KSPROPERTY_AUDIO_SURROUND_ENCODE
KSPROPERTY_AUDIO_3D_INTERFACE
if >= WINXP:
KSPROPERTY_AUDIO_PEAKMETER
KSPROPERTY_AUDIO_ALGORITHM_INSTANCE
KSPROPERTY_AUDIO_FILTER_STATE
KSPROPERTY_AUDIO_PREFERRED_STATUS
if >= VISTA:
KSPROPERTY_AUDIO_PEQ_MAX_BANDS
KSPROPERTY_AUDIO_PEQ_NUM_BANDS
KSPROPERTY_AUDIO_PEQ_BAND_CENTER_FREQ
KSPROPERTY_AUDIO_PEQ_BAND_Q_FACTOR
KSPROPERTY_AUDIO_PEQ_BAND_LEVEL
KSPROPERTY_AUDIO_CHORUS_MODULATION_RATE
KSPROPERTY_AUDIO_CHORUS_MODULATION_DEPTH
KSPROPERTY_AUDIO_REVERB_TIME
KSPROPERTY_AUDIO_REVERB_DELAY_FEEDBACK
KSPROPERTY_AUDIO_POSITIONEX
KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY
if >= WIN8:
KSPROPERTY_AUDIO_PRESENTATION_POSITION
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION
KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION
KSPROPERTY_AUDIO_PEAKMETER2
if >= WINBLUE:
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION
KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED
if >= WIN10_RS1:
KSPROPERTY_AUDIO_MIC_SENSITIVITY
KSPROPERTY_AUDIO_MIC_SNR
if >= WIN10_RS4:
KSPROPERTY_AUDIO_MIC_SENSITIVITY2
It's won't be too much longer until I am am ready to have the code tested.
you can view the changes I have made so far on the develop branch https://github.com/kdschlosser/pyWinCoreAudio/tree/develop
OK I have a version that is functional. it is in the develop branch. You can install it using
pip install https://github.com/kdschlosser/pyWinCoreAudio/tarball/develop
There is an example.py file in the develop branch that you can use as a guide.
when you make the call to pyWinCoreAudio.devices()
here is going to be a notice that gets printed out. This notice is extremely important so please read it. It will keep your program stable by following the directions in it. If you do not follow the directions you can potentially have a memory leak or end up with an app crash. If you do not want the notice to appear pass False
in the call to pyWinCoreAudio.devices()
It is extremely important that you follow the example.py file. If you do anything with the library at the root level of your module you MUST make sure that you delete each object that is created. Even when something is done in a for loop or a while loop a reference to the object will exist in globals()
so you have to make sure that it gets deleted at the end of each iteration.
I am still working on getting the KS properties working and also all of the notifications. The default endpoint notification, session volume and endpoint volume notifications are functional. YOU MUST USE the exact same parameter names seen in the example for the callbacks. If you do not it will not function. The callback system holds a weak reference to the callbacks and also a weak reference to any devices, endpoint, sessions or interfaces passed when registering a callback. so you can delete the callback function and this will cause it to get unregistered. if a device, endpoint, session or interface that has been passed no longer exists the callback will get removed and you will need to register the callback again once the device, endpoint, session or interface becomes available again.
rule of thumb with registering callbacks. If the signal has "DEVICE" in the name then you can pass a device object when registering if you want only notifications for that device. There are 2 signals where this doesn't hold true, the signals are ON_DEVICE_ADDED
and ON_DEVICE_REMOVED
. You cannot pass a device object when registering a callback for those 2 signals. If the signal name has "ENDPOINT" in the name you can pass a device object when registering. This will enable getting notifications for all endpoints attached to that device. You can also target a specific endpoint by passing both the device object and an endpoint that belongs to that device. If you do that you will get notifications only for that endpoint. If "SESSION" is in the name for the signal you can pass device, device and endpoint or device, endpoint and session. If "INTERFACE" is in the same you can pass device, device and endpoint or device, endpoint and interface.
You can use the signals in a dynamic nature by using the ON_DEVICE_ADDED and ON_DEVICE_REMOVED signals and registering and unregistering callbacks inside of the functions you pass to those 2 signals.
For some bat shit crazy reason the notification API for core audio likes to send multiple notifications for the same thing. I have filter this out in the 3 tested signals. I have not done this with any of the other signals.
The callback system uses a threadworker to make the call to the callback you provide. This is done so the core audio notification system doesn't get held up if you need to do some lengthy processing. It is also done to handle unhandled exceptions that might be in your code. The threadworker will catch any exceptions that are unhandled and it will print out the exception and the threadworker will continue along it merry way. The threadworker is a daemon thread so when the thread that imports pyWinCoreAudio terminates so does the threadworker. My recommendation is to only import pyWinCoreAudio from the main thread. The threadworker thread also exits after a period of activity. This is done to release resources. While I know it is not a lot of resources it holds in the first place I am just a stickler for giving back when it is not being used. Once a notification comes in the thread will restart and if a lot of notifications come in back to back it will process all of the notifications and then terminate after the timeout period has expired.
The API is a whole lot easier to use with this new version. The majority of the objects that you use from the library are the ctypes objects. I did this to allow a user to add onto the library if they want.
Here is the link to the development branch once again. https://github.com/kdschlosser/pyWinCoreAudio/tree/develop
Hi, sorry if I missed something, but I'm running the example code from your develop branch, and I still can't figure out how to achive this:
Can anyone give some suggest or couple-string-example how:
- Switch default device, i mean "Speakers" to "Headphones" and how i can get event callbacks for it?
I've managed to filter the devices and endpoints that I'm interested in:
AMD High Definition Audio Device
endpoints:
endpoint: 1 - DELL P2418HT (AMD High Definition Audio Device)
description: 1 - DELL P2418HT
type: Unknown
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {4EFCDC5E-1A0D-425B-A4C2-86C386D21970}
physical_speakers: 2.0
system_effects: False
hdcp_capable: True
ai_capable: False
connector_type: Physical External
connector_name:
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: True
channel_config: 2.0
input: None
output: None
audio_channels: [<pyWinCoreAudio.mmdeviceapi.AudioChannel object at 0x000001D0571B17F0>, <pyWinCoreAudio.mmdeviceapi.AudioChannel object at 0x000001D0571B1310>]
endpoint: 6 - LG TV (AMD High Definition Audio Device)
description: 6 - LG TV
type: Unknown
data flow: Render
form_factor: Digital Audio Display Device
full_range_speakers: 0
guid: {8A336AE5-279B-4DE1-803C-8F98D662A090}
physical_speakers: 2.0
system_effects: False
hdcp_capable: True
ai_capable: True
connector_type: Physical External
connector_name:
connector_subtype: HDMI Interface
connector_location: On separate chassis, HDMI
connector_style: HDMI
presence_detection: True
connector_color: (0, 0, 0, 255)
is_connected: True
channel_config: 2.0
input: None
output: None
audio_channels: [<pyWinCoreAudio.mmdeviceapi.AudioChannel object at 0x000001D0571B1B20>, <pyWinCoreAudio.mmdeviceapi.AudioChannel object at 0x000001D0571B10A0>]
Realtek High Definition Audio
endpoints:
endpoint: Speakers (Realtek High Definition Audio)
description: Speakers
type: Unknown
data flow: Render
form_factor: Speakers
full_range_speakers: 2.0
guid: {6315A238-B914-4369-B086-7FCD1654E714}
physical_speakers: 2.0
system_effects: False
hdcp_capable: False
ai_capable: False
connector_type: Physical External
connector_name: Realtek HD Audio output
connector_subtype: Speaker
connector_location: On primary chassis, Rear-mounted panel
connector_style: 1/8"
presence_detection: True
connector_color: (0, 255, 0, 255)
is_connected: True
channel_config: 2.0
input: None
output: None
audio_channels: [<pyWinCoreAudio.mmdeviceapi.AudioChannel object at 0x000001D0571B1F40>, <pyWinCoreAudio.mmdeviceapi.AudioChannel object at 0x000001D0571B1280>]
And I can get the events for what I'm looking for, no problems.
OnPropertyValueChanged
Default changed: AMD High Definition Audio Device.6 - LG TV (AMD High Definition Audio Device) role: Multimedia flow: Render
Default changed: AMD High Definition Audio Device.6 - LG TV (AMD High Definition Audio Device) role: Console flow: Render
Default changed: AMD High Definition Audio Device.6 - LG TV (AMD High Definition Audio Device) role: Communications flow: Render
OnPropertyValueChanged
Default changed: Realtek High Definition Audio.Speakers (Realtek High Definition Audio) role: Multimedia flow: Render
Default changed: Realtek High Definition Audio.Speakers (Realtek High Definition Audio) role: Console flow: Render
Default changed: Realtek High Definition Audio.Speakers (Realtek High Definition Audio) role: Communications flow: Render
OnPropertyValueChanged
Default changed: AMD High Definition Audio Device.1 - DELL P2418HT (AMD High Definition Audio Device) role: Multimedia flow: Render
Default changed: AMD High Definition Audio Device.1 - DELL P2418HT (AMD High Definition Audio Device) role: Console flow: Render
Default changed: AMD High Definition Audio Device.1 - DELL P2418HT (AMD High Definition Audio Device) role: Communications flow: Render
But my goal is to switch the default output device like so:
This is the first time that I'm messing with a windows API, so any pointers will be appreciated.
Also, thank you for your work!
But my goal is to switch the default output device like so:
Answering my own question, you must call the method 'set_default' of the desired endpoint, with the argument being the role, as described here: https://docs.microsoft.com/en-us/windows/win32/api/mmdeviceapi/ne-mmdeviceapi-erole
Something like this:
if endpoint.guid == '{6315A238-B914-4369-B086-7FCD1654E714}':
endpoint.set_default(0)
Hope this will be helpful for someone.
You can use the GUID for comparison or you can also use the name. The GUID can and will change if the sound device is a USB device and you plug the device into a different USB port. The GUID can also change if you update the drivers. The GUID is a little harder to locate and using the device name and the endpoint name to target a specific endpoint is easiest.
The ERole and EDataFlow enumerations are available in the library,
from pyWinCoreAudio.mmdeviceapi import ERole, EDataFlow
ERole.eConsole
ERole.eMultimedia
ERole.eCommunications
EDataFlow.eRender
EDataFlow.eCapture
The file structure of the library matches the Windows SDK. How this helps is when you are reading documentation like the link you posted. If you scroll down the page near the bottom is the section "Requirements" If you look at the field labeled "Header" it is going to tell you the Windows SDK file where that piece of API is located. In the case of the link you posted the header file is "mmdeviceapi.h"
Microsoft has the use of roles for defining the default endpoint and for the most part they really do not get used. It is common when setting the default endpoint to set the endpoint as the default for eConsole and eMultimedia to the same endpoint.
The Windows Core Audio API is a rather tangled interwoven mess and I have done my best to untangle it and organize the various parts so they make sense. Endpoints are grouped together by device and sessions are grouped together by endpoint. It is easiest to think of an endpoint as a jack or a group of jacks. it is what the sound gets output to or where sound is captured from. Sessions are opened up by programs/apps to play or record. If you open up the Volume Mixer in Windows you will be given a volume control for each session that exists. You also have the ability to alter the volume of sessions from the library as well.
With some creativity you can do some pretty wild things. An example is detecting when there is sound heard on a microphone or when sound starts and stops playing. You use the peak meter to accomplish those things.
Because you can get notifications for plugging and unplugging from different jacks you can use the library to detect when you plug in your headphones and then start your favorite music application. Another is when you unplug your headphones have the library turn the volume down and or close the music application.
Hello! Thanks a lot for you'r lib, it's fantastic!
You have done a great job and made the most powerful lib for Windows Core Audio API! Thanks a lot yet!
But can u make some 'quik start' or some little examples for each "ability". I mean just little example how change 'Volume Level' or 'mute' e.t.c
I'm just started programmon on python and some things is hard for me yet.
Can anyone give some suggest or couple-string-example how:
P.S. I can't understand some thing. In other issue author says he don't update this lib for python 3.7+ but in pypi.org i found this lib for python 3.7-3.9 and without descriprion and other links and by other author. It's mean good news for us and you finally updated for python 3 or it's some other people did it?