Selecting an output device (Web)
A desktop user has a USB audio interface plugged in for practice, Bluetooth headphones for the couch, and the built-in speakers for casual listening โ they want to pick where alphaTab's audio comes out. Build a device dropdown, hand the selection back to alphaTab, and the audio graph re-routes without stopping playback.
Web-only. Runs against the browser's Audio Output Devices API โ the same experimental setSinkId support used by <audio> and <video> elements. Browser coverage is uneven; see caniuse. On .NET the output device is chosen through NAudio; on Android through AudioTrack. Point native readers at those pages.
Three async methodsโ
api.enumerateOutputDevices()โ returns aPromise<ISynthOutputDevice[]>. Each device exposesdeviceIdandlabel. Requesting the list triggers a browser permission prompt when needed; without permission you get an empty array.api.setOutputDevice(device)โ accepts one of the returned entries ornullto fall back to the system default. Returns aPromisethat resolves once the audio graph is rewired.api.getOutputDevice()โ returns the device previously set throughsetOutputDevice, ornullwhen alphaTab is still on the default. Useful for restoring UI state after a page reload.
Devices can appear and disappear at runtime โ a Bluetooth headset connects, a USB interface unplugs. Enumerate again when you know the environment changed, or listen for the navigator.mediaDevices.devicechange event and refresh your dropdown from there.
Show it in codeโ
import * as alphaTab from '@coderline/alphatab';
const container = getAlphaTabContainer();
const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp' },
player: {
playerMode: alphaTab.PlayerMode.EnabledSynthesizer,
},
});
async function buildDeviceDropdown(select) {
const devices = await api.enumerateOutputDevices();
select.replaceChildren();
const defaultOption = new Option('System default', '');
select.append(defaultOption);
for (const device of devices) {
select.append(new Option(device.label, device.deviceId));
}
const current = await api.getOutputDevice();
select.value = current ? current.deviceId : '';
select.addEventListener('change', async () => {
const picked = devices.find((d) => d.deviceId === select.value) ?? null;
await api.setOutputDevice(picked);
});
}
navigator.mediaDevices.addEventListener('devicechange', () => {
buildDeviceDropdown(document.querySelector('#audio-out'));
});
buildDeviceDropdown(document.querySelector('#audio-out'));
getAlphaTabContainer() is a placeholder for the platform-specific step of obtaining the render target โ on Web that's a <div> alphaTab attaches to.
Where to look nextโ
api.enumerateOutputDevices,api.setOutputDevice, andapi.getOutputDevicein the reference.ISynthOutputDeviceโ the shape of each entry returned byenumerateOutputDevices.- Web Audio and AudioWorklet โ the browser audio backend the routing decision applies to.
- NAudio (.NET) and AudioTrack (Android) โ the equivalent routing story on the other runtimes.
- Audio buffer size โ pair a routing change with a matching buffer adjustment when latency matters.