ch output: per-channel output routing dropdowns
- Added GET/POST /api/channel-output endpoints for per-channel output routing (playback_1 / playback_2 / both) - Added output dropdowns to CH 1 and CH 2 cards in Audio Interface - Added setChOutput() and loadChOutput() JS functions - Updated connect_fx_ports to read per-channel output config
This commit is contained in:
@@ -300,7 +300,14 @@ body{display:flex;flex-direction:column;max-height:100vh;user-select:none;-webki
|
||||
<option value="backing_tracks">📻 Backing</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="font-size:9px;color:var(--text2);margin-top:2px">Output: Main L/R (Scarlett 1+2)</div>
|
||||
<div style="font-size:9px;color:var(--text2);margin-top:2px;display:flex;align-items:center;justify-content:space-between">
|
||||
<span>Output:</span>
|
||||
<select id="ch1Output" onchange="setChOutput(1,this.value)" style="font-size:9px;padding:2px 4px;min-height:22px;border-radius:4px;border:1px solid var(--border);background:var(--surface);color:var(--text);font-family:var(--font)">
|
||||
<option value="playback_1">Output 1 (L)</option>
|
||||
<option value="playback_2">Output 2 (R)</option>
|
||||
<option value="both" selected>Both (L+R)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ch-card" id="ch2Card" style="background:var(--card2);border-radius:8px;padding:6px 8px;margin:4px 0;border:2px solid rgba(58,184,122,.25)">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">
|
||||
@@ -317,7 +324,14 @@ body{display:flex;flex-direction:column;max-height:100vh;user-select:none;-webki
|
||||
<option value="backing_tracks">📻 Backing</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="font-size:9px;color:var(--text2);margin-top:2px">Output: Main L/R (Scarlett 1+2)</div>
|
||||
<div style="font-size:9px;color:var(--text2);margin-top:2px;display:flex;align-items:center;justify-content:space-between">
|
||||
<span>Output:</span>
|
||||
<select id="ch2Output" onchange="setChOutput(2,this.value)" style="font-size:9px;padding:2px 4px;min-height:22px;border-radius:4px;border:1px solid var(--border);background:var(--surface);color:var(--text);font-family:var(--font)">
|
||||
<option value="playback_1">Output 1 (L)</option>
|
||||
<option value="playback_2">Output 2 (R)</option>
|
||||
<option value="both" selected>Both (L+R)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size:9px;color:var(--text3);padding:2px 0">Dual Mono: each channel has independent presets. Same instrument = shared presets.</div>
|
||||
</div>
|
||||
@@ -491,6 +505,19 @@ async function setAudioOutputDevice(id){
|
||||
hideLoading();
|
||||
toast('Output: '+id);
|
||||
}
|
||||
async function setChOutput(ch,port){
|
||||
try{
|
||||
await API._fetch('/api/channel-output',{method:'POST',body:JSON.stringify({ch,port})});
|
||||
toast('CH'+ch+': '+port);
|
||||
}catch(e){toast('Failed: '+e.message);}
|
||||
}
|
||||
async function loadChOutput(){
|
||||
try{
|
||||
const r=await API._fetch('/api/channel-output');
|
||||
if(r.ch1){const el=document.getElementById('ch1Output');if(el)el.value=r.ch1;}
|
||||
if(r.ch2){const el=document.getElementById('ch2Output');if(el)el.value=r.ch2;}
|
||||
}catch(e){}
|
||||
}
|
||||
function setChInstrument(idx,val){
|
||||
const arr=JSON.parse(localStorage.getItem('chInstruments')||'["guitar","bass"]');
|
||||
arr[idx]=val;
|
||||
@@ -848,7 +875,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();loadAudioDevices();loadHotspotStatus();loadBtStatus();loadBtMidi();return;}
|
||||
else if(view==='settings'){openOverlay('Settings');loadNetworkInfo();loadSystemInfo();loadAudioParams();loadAudioDevices();loadChOutput();loadHotspotStatus();loadBtStatus();loadBtMidi();return;}
|
||||
else if(view==='presets'){openOverlay('Presets');loadPresets();}
|
||||
else if(view==='snapshots'){openOverlay('Snapshots');loadSnapshots();}
|
||||
else if(view==='downloads')openOverlay('Downloads');
|
||||
@@ -862,6 +889,7 @@ function init(){
|
||||
loadSystemInfo();
|
||||
loadAudioParams();
|
||||
loadAudioDevices();
|
||||
loadChOutput();
|
||||
loadHotspotStatus();
|
||||
loadBtStatus();
|
||||
loadBtMidi();
|
||||
|
||||
Reference in New Issue
Block a user