【发布时间】:2022-01-11 06:20:35
【问题描述】:
我在 Chrome 中使用 WebUSB API。我可以与设备配对,声明一个接口,并开始监听一个入站中断端点,每次按下按钮时传输三个字节,释放按钮时再传输三个字节(这是供应商特定的 MIDI 实现)。
USBTransferInResult.data.buffer 包含它应该包含的所有字节,除非它们没有按传输方式提供。字节一次传输一个字节,除非我同时生成一堆数据,在这种情况下,同一个USBTransferInResult 中可能有多达三个或四个字节。
注意:此端点的最大数据包大小为8。我尝试将其设置为 1 和 256 之类的东西,但没有任何效果。
如果我连接所有的结果缓冲区,我会得到我期望的确切数据,但 API 肯定应该使每次传输(看似)原子。
这可能是由于供应商(Focusrite - 它是 Novation 产品)使用不符合标准的 MIDI 实现而做的一些时髦的事情的结果。我只是假设供应商更愿意将每个 MIDI 消息作为原子中断传输(而不是三个快速连续的单字节传输)传输,因为它会简化驱动程序并使其更加健壮。我看不出分解这些消息的好处。
注意:如果我启用experimental-usb-backend,我的USB设备将停止出现在对话框中(当requestDevice被调用时)。
这是我正在测试它的代码:
let DEVICE = undefined;
const connect = async function() {
/* Initialize the device, assign it to the global variable,
claim Interface 1, then invoke `listen`. */
const filters = [{vendorId: 0x1235, productId: 0x0018}];
DEVICE = await navigator.usb.requestDevice({filters});
await DEVICE.open();
await DEVICE.selectConfiguration(1);
await DEVICE.claimInterface(1);
listen();
};
const listen = async function() {
/* Recursively, listen for each interrupt transfer from
Endpoint 4, asking for upto 8 bytes each time, and then
logging each transfer (as a regular array of numbers). */
const result = await DEVICE.transferIn(4, 8);
const data = new Uint8Array(result.data.buffer);
console.log(Array.from(data));
listen();
};
// Note: The are a few lines of UI code here that provide a
// button for invoking the `connect` function above, and
// another button that invokes the `close` method of
// the USB device.
鉴于此问题在没有 USB 设备的情况下无法重现,我不想将其报告为错误,除非我确定它是一个错误。我希望这里有人可以帮助我。
我是否误解了 WebUSB API 的工作方式?
假设供应商可能打算将 MIDI 消息分解为单个字节是否合理?
【问题讨论】: