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

Add Xbox Live Communicator Support #1126

Open
Ryzee119 opened this issue Jun 28, 2022 · 4 comments
Open

Add Xbox Live Communicator Support #1126

Ryzee119 opened this issue Jun 28, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@Ryzee119
Copy link
Contributor

Ryzee119 commented Jun 28, 2022

Feature Request

Xbox Live Communicator (XBLC) is a a usb1.1 compliant device with two interfaces. One for Microphone and one for a mono speaker.

The usb device descriptor has previously been recorded here: https://xboxdevwiki.net/Xbox_Live_Communicator.

The speaker and microphone interface each has a single isochronous endpoint. Its unclear how the Xbox identifies the XBLC. It could either be by hardcoded PID/VIDs (unlikely), or more likely the bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol specifiers in the interface descriptors (this is how all other xbox peripherals are identified). The speaker and mic are likely differentiated by the direction of the isochronous endpoint, but could also be the interface index (unlikely though)

The headset supports the following audio sample rates (All at signed 16bit LE PCM samples). The units are in samples per second. As far as I can tell, the microphone and speaker always have the same sample rate:

  • 8000
  • 11025
  • 16000
  • 22050
  • 24000

For example at 24000 samples/sec, each USB frame (1000hz) sends 24x16bit samples which corresponds to 48bytes per USB frame which lines up with the Max packet size indicated in the interface descriptor.

If a sample rate does not divide evenly into USB frame 1ms blocks, the Xbox will add an additional sample every n frames. The formula for calculating this is 1000 / (sample_rate % 1000) = n, where % is the modulo operator.. For example at 11025 kHz, XDK will add an extra sample every 40 USB frames.

The sample rate is set by a control transfer to endpoint 0 of the device.

The control transfer for setting the sample rate has the following format (Ref usb2 spec 9.3)

bmRequestType = Host-to-device | Vendor | Interface (0x41)
bRequest = SET_FEATURE (0x03)
wValue = 0x100 | sample_rate
wIndex = 0x0000
wLength = 0x0000

Where sample_rate = 0 for 8000, up to 4 for 24000.

It is also not clear if the game can change this sample rate at any time, all games I tested only did it once after connection. Doing some testing in nxdk seemed to caused garbled audio if I attempted to change it a second time but this could be a bug elsewhere.

There is also a secondary control transfer that can occur. It is not exacty clear on its purpose, however I believe it is to do with Auto gain control for the micrphone. Ref https://web.archive.org/web/20200521011406/http://www.kako.com/neta/2005-009/uac3556b.pdf, Section 3.2

It has the following format:

bmRequestType = Host-to-device | Vendor | Interface (0x41)
bRequest = SET_FEATURE (0x03)
wValue = 0x0001 or 0x0000 (enable or disable?)
wIndex = 0x0001
wLength = 0x0000

Where wValue = 0 or 1 to enable or disable this feature

I have not observed any other usb transfers to the device.

I have written a functioning nxdk driver here https://github.com/Ryzee119/nxdk/blob/xblc/lib/usb/libusbohci_xbox/xblc_driver.c fo ref.

I can work on this, and will communicate progress here.

Alternatives

No response

Additional Context

No response

@Ryzee119 Ryzee119 added the enhancement New feature or request label Jun 28, 2022
@mborgerson
Copy link
Member

Related #389

@Ryzee119
Copy link
Contributor Author

One initial hurdle is that upstream qemu says it does not support isochronous endpoints on its OHCI backend
https://github.com/qemu/qemu/blob/5c8463886d50eeb0337bd121ab877cf692731e36/hw/usb/hcd-ohci.c#L21

Although its not clear whats working or not.

And ofcourse we need a way of linking user's audio devices into the XBLC backend and a corresponding GUI element.

@Ryzee119
Copy link
Contributor Author

Ryzee119 commented Jul 2, 2022

The communicator is physically keyed so that it only fits on the front port. This represents port number 2 of the internal controller's hub.

I tested this by emulating it in the other port but the device will not function properly atleast in XDK based games.

@Ryzee119
Copy link
Contributor Author

Ryzee119 commented Jul 5, 2022

I have a mostly working xblc driver here: https://github.com/Ryzee119/xemu/blob/xblc1/hw/xbox/xblc.c
Still a couple issues with scheduling iso packets. Unclear why this is occuring as the USB frame counter is synced with the rest of the emulation. Its getting caught up in here and seems to never be able to recover properly. Could be a bug in OHCI or even XDK?

https://github.com/mborgerson/xemu/blob/30042e809152b6c069611f13ab8e57739ebf4a16/hw/usb/hcd-ohci.c#L689-L697

For windows we also need to remove this:
https://github.com/mborgerson/xemu/blob/9c06980275b6b31fc9f1b7f7df9ac692dad508d8/softmmu/vl.c#L2969-L2973

Perhaps we need to move to a SDL audio driver backend?

It will just take the default microphone input set by your PC. The audio output is mixed into your default audio out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants