diff --git a/server/src/wled_controller/static/js/app.ts b/server/src/wled_controller/static/js/app.ts
index 51a3391..dc474ae 100644
--- a/server/src/wled_controller/static/js/app.ts
+++ b/server/src/wled_controller/static/js/app.ts
@@ -148,7 +148,7 @@ import {
showAudioSourceModal, closeAudioSourceModal, saveAudioSource,
editAudioSource, cloneAudioSource, deleteAudioSource,
testAudioSource, closeTestAudioSourceModal,
- refreshAudioDevices, onBandPresetChange,
+ refreshAudioDevices,
} from './features/audio-sources.ts';
// Layer 5: value sources
@@ -474,7 +474,6 @@ Object.assign(window, {
testAudioSource,
closeTestAudioSourceModal,
refreshAudioDevices,
- onBandPresetChange,
// value sources
showValueSourceModal,
diff --git a/server/src/wled_controller/static/js/features/audio-sources.ts b/server/src/wled_controller/static/js/features/audio-sources.ts
index ec114bb..f73d00f 100644
--- a/server/src/wled_controller/static/js/features/audio-sources.ts
+++ b/server/src/wled_controller/static/js/features/audio-sources.ts
@@ -18,7 +18,9 @@ import { showToast, showConfirm, lockBody, unlockBody } from '../core/ui.ts';
import { Modal } from '../core/modal.ts';
import { ICON_MUSIC, getAudioSourceIcon, ICON_AUDIO_TEMPLATE, ICON_AUDIO_INPUT, ICON_AUDIO_LOOPBACK } from '../core/icons.ts';
import { EntitySelect } from '../core/entity-palette.ts';
+import { IconSelect } from '../core/icon-select.ts';
import { TagInput } from '../core/tag-input.ts';
+import * as P from '../core/icon-paths.ts';
import { loadPictureSources } from './streams.ts';
let _audioSourceTagsInput: TagInput | null = null;
@@ -50,11 +52,23 @@ class AudioSourceModal extends Modal {
const audioSourceModal = new AudioSourceModal();
-// ── EntitySelect instances for audio source editor ──
+// ── EntitySelect / IconSelect instances for audio source editor ──
let _asTemplateEntitySelect: EntitySelect | null = null;
let _asDeviceEntitySelect: EntitySelect | null = null;
let _asParentEntitySelect: EntitySelect | null = null;
let _asBandParentEntitySelect: EntitySelect | null = null;
+let _asBandIconSelect: IconSelect | null = null;
+
+const _svg = (d: string): string => ``;
+
+function _buildBandItems() {
+ return [
+ { value: 'bass', icon: _svg(P.volume2), label: t('audio_source.band.bass'), desc: '20–250 Hz' },
+ { value: 'mid', icon: _svg(P.music), label: t('audio_source.band.mid'), desc: '250–4000 Hz' },
+ { value: 'treble', icon: _svg(P.zap), label: t('audio_source.band.treble'), desc: '4k–20k Hz' },
+ { value: 'custom', icon: _svg(P.slidersHorizontal), label: t('audio_source.band.custom') },
+ ];
+}
// ── Modal ─────────────────────────────────────────────────────
@@ -94,6 +108,7 @@ export async function showAudioSourceModal(sourceType: any, editData?: any) {
} else if (editData.source_type === 'band_extract') {
_loadBandParentSources(editData.audio_source_id);
(document.getElementById('audio-source-band') as HTMLSelectElement).value = editData.band || 'bass';
+ _ensureBandIconSelect();
(document.getElementById('audio-source-freq-low') as HTMLInputElement).value = String(editData.freq_low ?? 20);
(document.getElementById('audio-source-freq-high') as HTMLInputElement).value = String(editData.freq_high ?? 20000);
onBandPresetChange();
@@ -111,6 +126,7 @@ export async function showAudioSourceModal(sourceType: any, editData?: any) {
} else if (sourceType === 'band_extract') {
_loadBandParentSources();
(document.getElementById('audio-source-band') as HTMLSelectElement).value = 'bass';
+ _ensureBandIconSelect();
(document.getElementById('audio-source-freq-low') as HTMLInputElement).value = '20';
(document.getElementById('audio-source-freq-high') as HTMLInputElement).value = '20000';
onBandPresetChange();
@@ -357,6 +373,21 @@ function _loadMultichannelSources(selectedId?: any) {
}
}
+function _ensureBandIconSelect() {
+ const sel = document.getElementById('audio-source-band') as HTMLSelectElement | null;
+ if (!sel) return;
+ if (_asBandIconSelect) {
+ _asBandIconSelect.updateItems(_buildBandItems());
+ return;
+ }
+ _asBandIconSelect = new IconSelect({
+ target: sel,
+ items: _buildBandItems(),
+ columns: 2,
+ onChange: () => onBandPresetChange(),
+ });
+}
+
function _loadBandParentSources(selectedId?: any) {
const select = document.getElementById('audio-source-band-parent') as HTMLSelectElement | null;
if (!select) return;
diff --git a/server/src/wled_controller/templates/modals/audio-source-editor.html b/server/src/wled_controller/templates/modals/audio-source-editor.html
index f1aa0f5..60fd296 100644
--- a/server/src/wled_controller/templates/modals/audio-source-editor.html
+++ b/server/src/wled_controller/templates/modals/audio-source-editor.html
@@ -99,7 +99,7 @@
Select a frequency band preset or custom range
-