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;
export const getAudioContext = () => {
if (!audioContext) {
export const getAudioContext = (reset) => {
if (!audioContext || reset) {
audioContext = new AudioContext();
}
return audioContext;

View File

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

View File

@ -1,6 +1,6 @@
import React from 'react';
// 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 (
<select
onClick={onClick}
@ -8,9 +8,6 @@ export function SelectInput({ value, options, onChange, onClick, placeholder })
value={value ?? ''}
onChange={(e) => onChange(e.target.value)}
>
<option disabled value="">
{`${placeholder ?? 'select an option'}`}
</option>
{Array.from(options.keys()).map((id) => (
<option key={id} className="bg-background" value={id}>
{options.get(id)}