system standard resets audio context

This commit is contained in:
Jade Rowland 2023-12-17 23:15:38 -05:00
parent f45a3933de
commit 48fa04f164
3 changed files with 14 additions and 11 deletions

View File

@ -28,8 +28,8 @@ export const resetLoadedSounds = () => soundMap.set({});
let audioContext; let audioContext;
export const getAudioContext = () => { export const getAudioContext = (reset) => {
if (!audioContext) { if (!audioContext || reset) {
audioContext = new AudioContext(); audioContext = new AudioContext();
} }
return audioContext; return audioContext;

View File

@ -3,14 +3,19 @@ import { getAudioContext, initializeAudioOutput } from '@strudel.cycles/webaudio
import { SelectInput } from './SelectInput'; import { SelectInput } from './SelectInput';
const initdevices = new Map(); const initdevices = new Map();
const defaultDeviceName = 'System Standard';
// Allows the user to select an audio interface for Strudel to play through // Allows the user to select an audio interface for Strudel to play through
export function AudioDeviceSelector({ audioDeviceName, onChange }) { export function AudioDeviceSelector({ audioDeviceName, onChange }) {
const [devices, setDevices] = useState(initdevices); const [devices, setDevices] = useState(initdevices);
const devicesInitialized = devices.size > 0; const devicesInitialized = devices.size > 0;
const setAudioDevice = useCallback(async (id) => { const setAudioDevice = useCallback(async (id) => {
const audioCtx = getAudioContext(); const isValidID = (id ?? '').length > 0;
await audioCtx.setSinkId(id); // reset the audio context and dont set the sink id if it is invalid AKA System Standard selection
const audioCtx = getAudioContext(!isValidID);
if (isValidID) {
await audioCtx.setSinkId(id);
}
initializeAudioOutput(); initializeAudioOutput();
}); });
const initializedevices = useCallback(async () => { const initializedevices = useCallback(async () => {
@ -18,6 +23,7 @@ export function AudioDeviceSelector({ audioDeviceName, onChange }) {
let mediaDevices = await navigator.mediaDevices.enumerateDevices(); let mediaDevices = await navigator.mediaDevices.enumerateDevices();
mediaDevices = mediaDevices.filter((device) => device.kind === 'audiooutput' && device.deviceId !== 'default'); mediaDevices = mediaDevices.filter((device) => device.kind === 'audiooutput' && device.deviceId !== 'default');
const devicesMap = new Map(); const devicesMap = new Map();
devicesMap.set(defaultDeviceName, '');
mediaDevices.forEach((device) => { mediaDevices.forEach((device) => {
devicesMap.set(device.label, device.deviceId); devicesMap.set(device.label, device.deviceId);
}); });
@ -33,7 +39,7 @@ export function AudioDeviceSelector({ audioDeviceName, onChange }) {
initializedevices().then((devices) => { initializedevices().then((devices) => {
const deviceID = devices.get(audioDeviceName); const deviceID = devices.get(audioDeviceName);
if (deviceID == null) { if (deviceID == null) {
onChange(''); onChange(defaultDeviceName);
return; return;
} }
setAudioDevice(deviceID); setAudioDevice(deviceID);
@ -52,7 +58,7 @@ export function AudioDeviceSelector({ audioDeviceName, onChange }) {
} }
const deviceID = devices.get(deviceName); const deviceID = devices.get(deviceName);
onChange(deviceName); onChange(deviceName);
deviceID && setAudioDevice(deviceID); setAudioDevice(deviceID);
}; };
const options = new Map(); const options = new Map();
Array.from(devices.keys()).forEach((deviceName) => { Array.from(devices.keys()).forEach((deviceName) => {
@ -62,7 +68,7 @@ export function AudioDeviceSelector({ audioDeviceName, onChange }) {
<SelectInput <SelectInput
options={options} options={options}
onClick={onClick} onClick={onClick}
placeholder="System Standard" placeholder={defaultDeviceName}
value={audioDeviceName} value={audioDeviceName}
onChange={onDeviceChange} onChange={onDeviceChange}
/> />

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
// value: ?ID, options: Map<ID, any>, onChange: ID => null, onClick: event => void, placeholder?: string // value: ?ID, options: Map<ID, any>, onChange: ID => null, onClick: event => void, placeholder?: string
export function SelectInput({ value, options, onChange, onClick, placeholder }) { export function SelectInput({ value, options, onChange, onClick }) {
return ( return (
<select <select
onClick={onClick} onClick={onClick}
@ -8,9 +8,6 @@ export function SelectInput({ value, options, onChange, onClick, placeholder })
value={value ?? ''} value={value ?? ''}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
> >
<option disabled value="">
{`${placeholder ?? 'select an option'}`}
</option>
{Array.from(options.keys()).map((id) => ( {Array.from(options.keys()).map((id) => (
<option key={id} className="bg-background" value={id}> <option key={id} className="bg-background" value={id}>
{options.get(id)} {options.get(id)}