useParameter
A parameter's value, re-rendering the component whenever it changes.
function useParameter<T>(parameter: ParameterLike<T>): T;useParameter(parameters.gain) returns the parameter's current value and
re-renders the component when it changes, whoever changes it: the host's
automation, a preset, another view, the audio side, or this UI.
import { Pressable, Text, View, useParameter } from '@soundor/react';
import type { ReactNode } from 'react';
import { parameters } from 'soundor:parameters';
function Button({
label,
selected = false,
onPress,
}: {
label: string;
selected?: boolean;
onPress: () => void;
}) {
return (
<Pressable
onPress={onPress}
accessibilityState={{ selected }}
style={({ pressed }) => ({
minWidth: 32,
alignItems: 'center',
paddingVertical: 4,
paddingHorizontal: 10,
borderRadius: 6,
backgroundColor: selected || pressed ? '#3a7bfd' : '#2a2c33',
})}
>
<Text style={{ color: 'white' }}>{label}</Text>
</Pressable>
);
}
function Row({ label, children }: { label: string; children: ReactNode }) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
<Text style={{ width: 64, color: '#8b8f98' }}>{label}</Text>
{children}
</View>
);
}
// One parameter of each type. Values are plain: a number in range (an int
// is rounded), a boolean, or one of an enum's values.
export default function Parameters() {
const gain = useParameter(parameters.gain);
const voices = useParameter(parameters.voices);
const bypass = useParameter(parameters.bypass);
const mode = useParameter(parameters.mode);
return (
<View style={{ gap: 10 }}>
<Row label="Gain">
<Button label="−" onPress={() => parameters.gain.set(gain - 0.1)} />
<Text style={{ width: 40, color: '#e6e7ea' }}>{gain.toFixed(2)}</Text>
<Button label="+" onPress={() => parameters.gain.set(gain + 0.1)} />
</Row>
<Row label="Voices">
<Button label="−" onPress={() => parameters.voices.set(voices - 1)} />
<Text style={{ width: 40, color: '#e6e7ea' }}>{voices}</Text>
<Button label="+" onPress={() => parameters.voices.set(voices + 1)} />
</Row>
<Row label="Bypass">
<Button
label={bypass ? 'On' : 'Off'}
selected={bypass}
onPress={() => parameters.bypass.set(!bypass)}
/>
</Row>
<Row label="Mode">
{parameters.mode.info.values.map((value) => (
<Button
key={value}
label={value}
selected={value === mode}
onPress={() => parameters.mode.set(value)}
/>
))}
</Row>
</View>
);
}parameters.tsxSource- The parameter stays the source of truth. Show its value and change it
with
set(); do not copy it into React state, or the host's automation and presets will not show. - Changes arrive once a frame. A burst of changes (automation from the audio thread) re-renders once, with the latest value.
- Typed from the config: a
floatorintparameter gives anumber, aboolaboolean, anenumone of its values. - During a drag, bracket the
set()s withbeginGesture()andendGesture(), so the host records one edit:
const gain = useParameter(parameters.gain);
<View
onPointerDown={() => parameters.gain.beginGesture()}
onPointerMove={(event) => parameters.gain.set(valueAt(event.locationY))}
onPointerUp={() => parameters.gain.endGesture()}
/>;It takes anything with get() and subscribe(), as
soundor:parameters' parameters have. The
Parameters guide shows how to declare them and connect
them to audio.