m2jean / ToothTray

A tray icon in Windows task bar to quickly connect or disconnect bluetooth audio devices.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't build

steam3d opened this issue · comments

I downloaded missing nugget packages but still can't build the project
image

The project looks for the packages in its parent folder(..\packages\...). You can reinstall the Nuget packages to correct the paths or put the solution file in the parent folder.

Thx. I finally builded the app. I try to rewrite on c#. I got all necessary data PKEY_Device_ContainerId and audio endpoints state etc. But i can't understand how you connect specific bluetooth headphones.
I do't not know c++, but i think it is action when i click on tray menu item:

bool ToothTrayMenu::TryHandleCommand(int commandId) {
    std::unordered_map<unsigned int, MenuData>::iterator pMenuData = m_menuData.find((unsigned int)commandId);
    if (pMenuData == m_menuData.end())
        return false;

    MenuData& menuData = (*pMenuData).second;
    if (menuData.pConnector.IsConnected())
        menuData.pConnector.Disconnect();
    else
        menuData.pConnector.Connect();

    return true;
}

which calls the function

void Connect() {
        GetKsBtAudioProperty(KSPROPERTY_ONESHOT_RECONNECT);
    }
    void BluetoothConnector::GetKsBtAudioProperty(ULONG property) {
    KSPROPERTY ksProperty;
    ksProperty.Set = KSPROPSETID_BtAudio;
    ksProperty.Id = property;
    ksProperty.Flags = KSPROPERTY_TYPE_GET;

    ULONG bytesReturned;
    for (winrt::com_ptr<IKsControl> &ksControl : m_ksControls) {
        HRESULT hr = ksControl->KsProperty(&ksProperty, sizeof(ksProperty), NULL, 0, &bytesReturned);
        DebugLogHresult(hr);
    }

But there is no identifier here to understand which device it will connect to.
Could you help me figure out how to specify the specific device that should be connected?

See

ite->second.addConnectorControl(pKsControl, state);
, an IKsControl is retrieved for each bluetooth audio device during enumeration, which is further wrapped into a MenuData and assigned a command id. The device and the corresponding IKsControl is identified by the command id.

Thx. I figured out how it works. I spent some time testing and found some issues.
The headphones typically have two audio endpoints as you describe.
image
For example, my headphones have two audio endpoints. AudioSink and Handfree. There are also some services for media keys on headphones Remote control and Remotely controllable device.

When i call the KSPROPERTY_ONESHOT_DISCONNECT both AudioSink and Handfree disconnected and then Handfree immediately reconnected and after about 30-60 sec the AudioSink is also connect.

When i turn off Handfree service the KSPROPERTY_ONESHOT_DISCONNECT correctly disconnect device.

Then i went to the sound manager and manually disconnect the Handfree audio endpoint. (Selected item is "Disconnect")
image
And to my surprise the behavior is exactly the same as I described came out.

It seems that Windows performs additional operations to turn off the headphones, but I have not yet figured out what exactly

I have tested on my 2 headphones but didn't see what you described. When KSPROPERTY_ONESHOT_DISCONNECT is sent to a device's two IKsControl (one for Stereo and one for Hand-free Audio), my headphone disconnects from Windows as expected. The disconnection is acknowledged both by Windows and my headphone (with a voice saying "Disconnected").

It is possible that your problem is caused by the service 'AAP Serverthat my headphones don't have. Usually a Bluetooth device is only disconnected when all of its active connections are disconnected, so maybe your device have some connections other thanAudio SinkandHandfree`? Is there anything special when you enumerate audio endpoints?

I double checked. Only AudioSink has connector {2}.\?\bthenum. The Handfree never has connector "bt". So i can disconnect only for one AudioSink connector.
Much worse that when i connect AudioSink first turn on the Handfree after about 1-2 sec then switch to AudioSink.

The Handfree has only {2}.\\?\intelaudio#ctlr_dev_a0c8&linktype_03&devtype_00&ven_8086&dev_ae30&subsys_383417aa&rev_0001#5&38cf7c70&0&0000#{6994ad04-93ef-11d0-a3cc-00a0c9223196}

I have Windows 11 on my pc.

What about your headphones?

I'm using Win10 and my headphone connects to
{2}.\\?\bthenum#{0000110b-0000-1000-8000-00805f9b34fb}_vid&0001005d_pid&223b#7&1894c59e&0&7445ce1ba9a8_c00000000#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\src and {2}.\\?\bthhfenum#bthhfpaudio#8&9541f2&9&97#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\wave.

The different device id pattern is probably because of the audio driver on your PC. Have your tried to send disconnect signal to the handfree control? It might work even though it doesn't start with {2}.\\?\bth.

Interesting, Windows team have changed Bluetooth headphones behavior on Windows 11.
No, i thought only {2}.\\?\bth works. I will try Windows 10 first.

Yes. i have the same result as you describe on windows 10.
for comparison Windows 11:

AudioSink
{2}.\?\bthenum#{0000110b-0000-1000-8000-00805f9b34fb}_vid&0001004c_pid&200e#7&2ca24c83&0&d0654429c700_c00000000#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\src

Handfree
{2}.\?\intelaudio#ctlr_dev_a0c8&linktype_03&devtype_00&ven_8086&dev_ae30&subsys_383417aa&rev_0001#5&38cf7c70&0&0000#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\intcbttoporender_192000_000000008cfd595a_0

I will try to find is there any deference between connection on Windows 10 and Windows 11.