audio interface: separate input/output device selectors
- Added Output Device dropdown alongside Input Device - loadAudioDevices() now populates both dropdowns from the API and selects current values - Separated setAudioInputDevice / setAudioOutputDevice functions (each calls API with only its respective field) - Added input_device / output_device to GET /api/audio/profile response - Removed the old combined setAudioDevice function
This commit is contained in:
@@ -1353,6 +1353,8 @@ class WebServer:
|
||||
"rate": profile["rate"],
|
||||
"jack_running": True,
|
||||
"xrun_count": xruns,
|
||||
"input_device": self.deps.audio_system.config.input_device,
|
||||
"output_device": self.deps.audio_system.config.output_device,
|
||||
}
|
||||
|
||||
@app.post("/api/audio/profile")
|
||||
|
||||
@@ -283,7 +283,8 @@ body{display:flex;flex-direction:column;max-height:100vh;user-select:none;-webki
|
||||
<div class="setting-row"><span class="sr-label">🔗 Routing</span><span class="sr-value" id="routingModeLabel">4CM</span><button class="sr-action" id="routingModeToggle">Toggle</button></div>
|
||||
</div>
|
||||
<div class="setting-group" id="section-interface"><div class="setting-group-title">🎚 Audio Interface</div>
|
||||
<div class="setting-row"><span class="sr-label">🔌 Input Device</span><select id="audioInputDevice" style="flex:1;min-width:0;font-size:10px;padding:4px 6px;min-height:30px" onchange="setAudioDevice(this.value)"></select></div>
|
||||
<div class="setting-row"><span class="sr-label">🔌 Input Device</span><select id="audioInputDevice" onchange="setAudioInputDevice(this.value)" style="flex:1;min-width:0;font-size:10px;padding:4px 6px;min-height:30px"><option value="">Loading...</option></select></div>
|
||||
<div class="setting-row"><span class="sr-label">🔊 Output Device</span><select id="audioOutputDevice" onchange="setAudioOutputDevice(this.value)" style="flex:1;min-width:0;font-size:10px;padding:4px 6px;min-height:30px"><option value="">Loading...</option></select></div>
|
||||
<div class="ch-card" id="ch1Card" style="background:var(--card2);border-radius:8px;padding:6px 8px;margin:4px 0;border:2px solid rgba(232,160,48,.25)">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">
|
||||
<span style="font-size:11px;font-weight:700;color:var(--amber)">🔴 CH 1 — Input 1/L</span>
|
||||
@@ -450,10 +451,36 @@ function hideLoading(){
|
||||
|
||||
// Audio Interface helpers
|
||||
async function loadAudioDevices(){
|
||||
const sel=document.getElementById('audioInputDevice');
|
||||
if(!sel)return;
|
||||
const inSel=document.getElementById('audioInputDevice');
|
||||
const outSel=document.getElementById('audioOutputDevice');
|
||||
if(!inSel||!outSel)return;
|
||||
const devs=await API.listAudioDevices();
|
||||
sel.innerHTML=(devs||[]).map(d=>'<option value="'+d.id+'">'+d.name+'</option>').join('')||'<option value="">No devices</option>';
|
||||
const opts=(devs||[]).map(d=>{
|
||||
const id='hw:'+d.card+','+d.device;
|
||||
return '<option value="'+id+'">'+d.name+' ('+d.desc+')</option>';
|
||||
}).join('')||'<option value="">No devices</option>';
|
||||
inSel.innerHTML=opts;
|
||||
outSel.innerHTML=opts;
|
||||
// Load current input/output from audio profile
|
||||
try{
|
||||
const p=await API.getAudioProfile();
|
||||
if(p.input_device)inSel.value=p.input_device;
|
||||
if(p.output_device)outSel.value=p.output_device;
|
||||
}catch(e){}
|
||||
}
|
||||
async function setAudioInputDevice(id){
|
||||
if(!id)return;
|
||||
showLoading('Switching input...');
|
||||
await API.saveSettings({input_device:id}).catch(()=>{});
|
||||
hideLoading();
|
||||
toast('Input: '+id);
|
||||
}
|
||||
async function setAudioOutputDevice(id){
|
||||
if(!id)return;
|
||||
showLoading('Switching output...');
|
||||
await API.saveSettings({output_device:id}).catch(()=>{});
|
||||
hideLoading();
|
||||
toast('Output: '+id);
|
||||
}
|
||||
function setChInstrument(idx,val){
|
||||
const arr=JSON.parse(localStorage.getItem('chInstruments')||'["guitar","bass"]');
|
||||
@@ -470,13 +497,7 @@ function toggleChPower(idx){
|
||||
btn.style.color=on?'var(--text3)':'var(--green)';
|
||||
API.bypassToggle(channels[idx]||'guitar').catch(()=>{});
|
||||
}
|
||||
async function setAudioDevice(devId){
|
||||
if(!devId)return;
|
||||
showLoading('Switching audio device...');
|
||||
await API.saveSettings({input_device:devId,output_device:devId}).catch(()=>{});
|
||||
hideLoading();
|
||||
toast('Device: '+devId);
|
||||
}
|
||||
|
||||
function loadChInstrumentState(){
|
||||
const arr=JSON.parse(localStorage.getItem('chInstruments')||'["guitar","bass"]');
|
||||
['ch1Instrument','ch2Instrument'].forEach((id,i)=>{
|
||||
@@ -818,7 +839,7 @@ function init(){
|
||||
btn.onclick=()=>{
|
||||
const view=btn.dataset.view;
|
||||
if(view==='main'){document.querySelectorAll('.tab-btn').forEach(b=>b.classList.remove('active'));btn.classList.add('active');}
|
||||
else if(view==='settings'){openOverlay('Settings');loadNetworkInfo();loadSystemInfo();loadAudioParams();loadHotspotStatus();loadBtStatus();loadBtMidi();return;}
|
||||
else if(view==='settings'){openOverlay('Settings');loadNetworkInfo();loadSystemInfo();loadAudioParams();loadAudioDevices();loadHotspotStatus();loadBtStatus();loadBtMidi();return;}
|
||||
else if(view==='presets'){openOverlay('Presets');loadPresets();}
|
||||
else if(view==='snapshots'){openOverlay('Snapshots');loadSnapshots();}
|
||||
else if(view==='downloads')openOverlay('Downloads');
|
||||
@@ -831,6 +852,7 @@ function init(){
|
||||
loadNetworkInfo();
|
||||
loadSystemInfo();
|
||||
loadAudioParams();
|
||||
loadAudioDevices();
|
||||
loadHotspotStatus();
|
||||
loadBtStatus();
|
||||
loadBtMidi();
|
||||
|
||||
Reference in New Issue
Block a user