Split media vs emit volume for radio and widget
This commit is contained in:
@@ -135,7 +135,9 @@ export class ItemEmitRuntime {
|
||||
});
|
||||
const gainValue = mix?.gain ?? 0;
|
||||
const panValue = mix?.pan ?? 0;
|
||||
output.gain.gain.linearRampToValueAtTime(gainValue, audioCtx.currentTime + 0.1);
|
||||
const emitVolumeRaw = Number(item.params.emitVolume ?? 100);
|
||||
const emitVolume = Number.isFinite(emitVolumeRaw) ? Math.max(0, Math.min(100, emitVolumeRaw)) / 100 : 1;
|
||||
output.gain.gain.linearRampToValueAtTime(gainValue * emitVolume, audioCtx.currentTime + 0.1);
|
||||
if (output.panner) {
|
||||
const resolvedPan = this.audio.getOutputMode() === 'mono' ? 0 : Math.max(-1, Math.min(1, panValue));
|
||||
output.panner.pan.linearRampToValueAtTime(resolvedPan, audioCtx.currentTime + 0.1);
|
||||
|
||||
@@ -203,8 +203,8 @@ export class RadioStationRuntime {
|
||||
}
|
||||
const streamUrl = String(item.params.streamUrl ?? '').trim();
|
||||
const enabled = item.params.enabled !== false;
|
||||
const volume = Number(item.params.volume ?? 50);
|
||||
const normalizedVolume = Number.isFinite(volume) ? Math.max(0, Math.min(100, volume)) / 100 : 0.5;
|
||||
const mediaVolume = Number(item.params.mediaVolume ?? 50);
|
||||
const normalizedVolume = Number.isFinite(mediaVolume) ? Math.max(0, Math.min(100, mediaVolume)) / 100 : 0.5;
|
||||
const effect = normalizeRadioEffect(item.params.effect);
|
||||
const effectValue = normalizeRadioEffectValue(item.params.effectValue);
|
||||
this.applyEffect(output, audioCtx, effect, effectValue);
|
||||
|
||||
@@ -48,11 +48,11 @@ const DEFAULT_CLOCK_TIME_ZONE_OPTIONS = [
|
||||
const DEFAULT_ITEM_TYPE_SEQUENCE: ItemType[] = ['clock', 'dice', 'radio_station', 'wheel', 'widget'];
|
||||
|
||||
const DEFAULT_ITEM_TYPE_EDITABLE_PROPERTIES: Record<ItemType, string[]> = {
|
||||
radio_station: ['title', 'streamUrl', 'enabled', 'channel', 'volume', 'effect', 'effectValue', 'facing', 'emitRange'],
|
||||
radio_station: ['title', 'streamUrl', 'enabled', 'channel', 'mediaVolume', 'effect', 'effectValue', 'facing', 'emitRange'],
|
||||
dice: ['title', 'sides', 'number'],
|
||||
wheel: ['title', 'spaces'],
|
||||
clock: ['title', 'timeZone', 'use24Hour'],
|
||||
widget: ['title', 'enabled', 'directional', 'facing', 'emitRange', 'useSound', 'emitSound'],
|
||||
widget: ['title', 'enabled', 'directional', 'facing', 'emitRange', 'emitVolume', 'useSound', 'emitSound'],
|
||||
};
|
||||
|
||||
const DEFAULT_ITEM_TYPE_GLOBAL_PROPERTIES: Record<ItemType, Record<string, string | number | boolean>> = {
|
||||
@@ -193,6 +193,8 @@ export function itemTypeLabel(type: ItemType): string {
|
||||
export function itemPropertyLabel(key: string): string {
|
||||
if (key === 'use24Hour') return 'use 24 hour format';
|
||||
if (key === 'emitRange') return 'emit range';
|
||||
if (key === 'mediaVolume') return 'media volume';
|
||||
if (key === 'emitVolume') return 'emit volume';
|
||||
if (key === 'useSound') return 'use sound';
|
||||
if (key === 'emitSound') return 'emit sound';
|
||||
return key;
|
||||
|
||||
@@ -749,7 +749,8 @@ function inferItemPropertyValueType(item: WorldItem, key: string): string | unde
|
||||
key === 'x' ||
|
||||
key === 'y' ||
|
||||
key === 'version' ||
|
||||
key === 'volume' ||
|
||||
key === 'mediaVolume' ||
|
||||
key === 'emitVolume' ||
|
||||
key === 'effectValue' ||
|
||||
key === 'facing' ||
|
||||
key === 'emitRange' ||
|
||||
@@ -2138,14 +2139,22 @@ function handleItemPropertyEditModeInput(code: string, key: string, ctrlKey: boo
|
||||
}
|
||||
const directional = ['on', 'true', '1', 'yes'].includes(normalized);
|
||||
signaling.send({ type: 'item_update', itemId, params: { directional } });
|
||||
} else if (propertyKey === 'volume') {
|
||||
} else if (propertyKey === 'mediaVolume') {
|
||||
const parsed = validateNumericItemPropertyInput(item, propertyKey, value, true);
|
||||
if (!parsed.ok) {
|
||||
updateStatus(parsed.message);
|
||||
audio.sfxUiCancel();
|
||||
return;
|
||||
}
|
||||
signaling.send({ type: 'item_update', itemId, params: { volume: parsed.value } });
|
||||
signaling.send({ type: 'item_update', itemId, params: { mediaVolume: parsed.value } });
|
||||
} else if (propertyKey === 'emitVolume') {
|
||||
const parsed = validateNumericItemPropertyInput(item, propertyKey, value, true);
|
||||
if (!parsed.ok) {
|
||||
updateStatus(parsed.message);
|
||||
audio.sfxUiCancel();
|
||||
return;
|
||||
}
|
||||
signaling.send({ type: 'item_update', itemId, params: { emitVolume: parsed.value } });
|
||||
} else if (propertyKey === 'effect') {
|
||||
const normalized = value.trim().toLowerCase() as EffectId;
|
||||
if (!EFFECT_IDS.has(normalized)) {
|
||||
|
||||
Reference in New Issue
Block a user