audio: replace profiles with direct sample rate + buffer size controls
- Removed audio profile grid and preset cards
- Added two dropdowns: Sample Rate (44.1/48/96/192 kHz) and Buffer
Size (64-2048 frames)
- New loadAudioParams() reads current rate+period from API
- New setAudioParams() POSTs {period, rate} directly on change
- Cleaned up unused CSS (.audio-profile-grid, .ap-card, .ap-key, etc.)
- Removed unused audioProfiles variable
This commit is contained in:
@@ -137,14 +137,6 @@ body{display:flex;flex-direction:column;max-height:100vh;user-select:none;-webki
|
||||
.wifi-connect-pw input{flex:1;padding:6px 8px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--text);font-family:var(--font);font-size:11px;outline:none;min-height:36px}
|
||||
.wifi-connect-pw input:focus{border-color:var(--amber)}
|
||||
.wifi-connect-pw button{min-width:52px;min-height:36px;border-radius:6px;border:1px solid var(--amber);background:var(--amber);color:#000;font-family:var(--font);font-size:11px;font-weight:700;cursor:pointer}
|
||||
.audio-profile-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px}
|
||||
.ap-card{background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:4px 6px;cursor:pointer;transition:all .12s;text-align:center}
|
||||
.ap-card:active{transform:scale(.95)}
|
||||
.ap-card.active{border-color:var(--amber);background:rgba(232,160,48,.08)}
|
||||
.ap-card .ap-key{font-size:9px;font-weight:600;text-transform:capitalize;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.ap-card .ap-desc{font-size:8px;color:var(--text2)}
|
||||
.ap-card.loading{opacity:.5;pointer-events:none}
|
||||
.ap-card.loading .ap-key::after{content:' ⟳';animation:spin .6s linear infinite;display:inline-block}
|
||||
|
||||
/* Loading overlay */
|
||||
.loading-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:300;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:8px}
|
||||
@@ -268,8 +260,24 @@ body{display:flex;flex-direction:column;max-height:100vh;user-select:none;-webki
|
||||
<div class="setting-row"><span class="sr-label">🔥 Hotspot</span><span class="sr-value" id="hotspotStatus">Off</span><button class="sr-action" id="hotspotToggle">Enable</button></div>
|
||||
</div>
|
||||
<div class="setting-group" id="section-audio"><div class="setting-group-title">Audio</div>
|
||||
<div class="setting-row"><span class="sr-label">🎛 Profile</span><span class="sr-value" id="audioProfileLabel">—</span></div>
|
||||
<div class="audio-profile-grid" id="audioProfileGrid"></div>
|
||||
<div class="setting-row"><span class="sr-label">🎛 Sample Rate</span>
|
||||
<select id="audioSampleRate" onchange="setAudioParams()" style="flex:1;max-width:140px;font-size:11px;padding:4px 8px;min-height:34px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--text);font-family:var(--font)">
|
||||
<option value="44100">44.1 kHz</option>
|
||||
<option value="48000" selected>48 kHz</option>
|
||||
<option value="96000">96 kHz</option>
|
||||
<option value="192000">192 kHz</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-row"><span class="sr-label">📦 Buffer Size</span>
|
||||
<select id="audioBufferSize" onchange="setAudioParams()" style="flex:1;max-width:140px;font-size:11px;padding:4px 8px;min-height:34px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--text);font-family:var(--font)">
|
||||
<option value="64">64</option>
|
||||
<option value="128">128</option>
|
||||
<option value="256" selected>256</option>
|
||||
<option value="512">512</option>
|
||||
<option value="1024">1024</option>
|
||||
<option value="2048">2048</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-row"><span class="sr-label">🎸 Instrument</span><span class="sr-value" id="instrumentLabel">Guitar</span><button class="sr-action" id="instrumentCycleBtn" style="min-width:44px;padding:4px 10px">Cycle</button></div>
|
||||
<div class="setting-row"><span class="sr-label">🔄 Channel Mode</span><span class="sr-value" id="channelModeLabel">Dual Mono</span><button class="sr-action" id="channelModeToggle">Toggle</button></div>
|
||||
<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>
|
||||
@@ -379,7 +387,11 @@ const API = {
|
||||
btMidiDisable:()=>API._fetch('/api/bluetooth/midi-disable',{method:'POST'}),
|
||||
btDiscoverableSet:(on)=>API._fetch('/api/bluetooth/discoverable',{method:'POST',body:JSON.stringify({on})}),
|
||||
listAudioProfiles:()=>API._fetch('/api/audio/profiles'),
|
||||
setAudioProfile:(p)=>API._fetch('/api/audio/profile',{method:'POST',body:JSON.stringify({profile:p})}),
|
||||
getAudioProfile:()=>API._fetch('/api/audio/profile'),
|
||||
setAudioProfile:(p)=>{
|
||||
if(typeof p==='string') return API._fetch('/api/audio/profile',{method:'POST',body:JSON.stringify({profile:p})});
|
||||
return API._fetch('/api/audio/profile',{method:'POST',body:JSON.stringify(p)});
|
||||
},
|
||||
getChannelMode:()=>API._fetch('/api/channel-mode'),
|
||||
setChannelMode:(m)=>API._fetch('/api/channel-mode',{method:'POST',body:JSON.stringify({channel_mode:m})}),
|
||||
getRouting:(ch)=>API._fetch('/api/routing?channel='+(ch||'guitar')),
|
||||
@@ -404,7 +416,6 @@ let currentChannel='guitar';
|
||||
let channels=['guitar','bass','keys','vocals','backing_tracks'];
|
||||
let presets=[];
|
||||
let snapshots={};
|
||||
let audioProfiles=[];
|
||||
let currentBank=0;
|
||||
let pollTimer=null;
|
||||
let tunerPollTimer=null;
|
||||
@@ -671,27 +682,13 @@ async function loadSystemInfo(){
|
||||
}catch(e){}
|
||||
}
|
||||
|
||||
async function loadAudioProfiles(){
|
||||
async function loadAudioParams(){
|
||||
try{
|
||||
audioProfiles=await API.listAudioProfiles();
|
||||
const grid=document.getElementById('audioProfileGrid');
|
||||
const cp=audioProfiles.current||'standard';
|
||||
grid.innerHTML='';
|
||||
(audioProfiles.profiles||[]).forEach(p=>{
|
||||
const d=document.createElement('div');
|
||||
d.className='ap-card'+(p.key===cp?' active':'');
|
||||
d.innerHTML='<div class="ap-key">'+p.key.replace(/_/g,' ')+'</div><div class="ap-desc">'+p.period+'fr / '+p.rate+'Hz</div>'+((p.key===cp)?'<div style="font-size:8px;color:var(--amber)">● Active</div>':'');
|
||||
d.onclick=async()=>{
|
||||
d.classList.add('loading');
|
||||
try{
|
||||
await API.setAudioProfile(p.key);
|
||||
toast('Profile: '+p.key);
|
||||
loadAudioProfiles();
|
||||
}catch(e){toast(e.message);d.classList.remove('loading');}
|
||||
};
|
||||
grid.appendChild(d);
|
||||
});
|
||||
document.getElementById('audioProfileLabel').textContent=cp;
|
||||
const p=await API.getAudioProfile();
|
||||
const rate=p.rate||48000;
|
||||
const period=p.period||256;
|
||||
document.getElementById('audioSampleRate').value=String(rate);
|
||||
document.getElementById('audioBufferSize').value=String(period);
|
||||
const cm=await API.getChannelMode();
|
||||
if(cm.channel_mode)document.getElementById('channelModeLabel').textContent=cm.channel_mode.replace(/-/g,' ').replace(/\b\w/g,l=>l.toUpperCase());
|
||||
const rt=await API.getRouting(currentChannel);
|
||||
@@ -699,6 +696,18 @@ async function loadAudioProfiles(){
|
||||
}catch(e){}
|
||||
}
|
||||
|
||||
async function setAudioParams(){
|
||||
const rate=parseInt(document.getElementById('audioSampleRate').value);
|
||||
const period=parseInt(document.getElementById('audioBufferSize').value);
|
||||
const btn=document.querySelector('.sn-btn[data-section="audio"]');
|
||||
if(btn)btn.textContent='⏳ Applying...';
|
||||
try{
|
||||
await API.setAudioProfile({period,rate});
|
||||
toast('Audio: '+rate+'Hz / '+period+'fr');
|
||||
}catch(e){toast('Failed: '+e.message);}
|
||||
if(btn)btn.textContent='🎛 Audio';
|
||||
}
|
||||
|
||||
async function loadBtStatus(){
|
||||
try{
|
||||
const st=await API.btStatus();
|
||||
@@ -809,7 +818,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();loadAudioProfiles();loadHotspotStatus();loadBtStatus();loadBtMidi();return;}
|
||||
else if(view==='settings'){openOverlay('Settings');loadNetworkInfo();loadSystemInfo();loadAudioParams();loadHotspotStatus();loadBtStatus();loadBtMidi();return;}
|
||||
else if(view==='presets'){openOverlay('Presets');loadPresets();}
|
||||
else if(view==='snapshots'){openOverlay('Snapshots');loadSnapshots();}
|
||||
else if(view==='downloads')openOverlay('Downloads');
|
||||
@@ -821,7 +830,7 @@ function init(){
|
||||
openOverlay('Settings');
|
||||
loadNetworkInfo();
|
||||
loadSystemInfo();
|
||||
loadAudioProfiles();
|
||||
loadAudioParams();
|
||||
loadHotspotStatus();
|
||||
loadBtStatus();
|
||||
loadBtMidi();
|
||||
@@ -844,11 +853,11 @@ function init(){
|
||||
document.getElementById('channelModeToggle').onclick=async()=>{
|
||||
const cur=document.getElementById('channelModeLabel').textContent.toLowerCase();
|
||||
const next=cur.includes('dual')?'stereo':'dual-mono';
|
||||
try{await API.setChannelMode(next);loadAudioProfiles();toast('Mode: '+next);}catch(e){toast(e.message);}
|
||||
try{await API.setChannelMode(next);loadAudioParams();toast('Mode: '+next);}catch(e){toast(e.message);}
|
||||
};
|
||||
document.getElementById('routingModeToggle').onclick=async()=>{
|
||||
const cur=document.getElementById('routingModeLabel').textContent;
|
||||
try{await API.setRouting(currentChannel,{routing_mode:cur==='MONO'?'4cm':'mono'});loadAudioProfiles();}catch(e){toast(e.message);}
|
||||
try{await API.setRouting(currentChannel,{routing_mode:cur==='MONO'?'4cm':'mono'});loadAudioParams();}catch(e){toast(e.message);}
|
||||
};
|
||||
document.getElementById('netModeToggle').onclick=async()=>{
|
||||
const lbl=document.getElementById('netDhcpStatus');
|
||||
@@ -883,7 +892,7 @@ function init(){
|
||||
await API.saveSettings({channel_mode:'dual-mono',brightness:8,tap_tempo:120});
|
||||
await API.setRouting(currentChannel,{routing_mode:'mono'}).catch(()=>{});
|
||||
toast('Defaults restored');
|
||||
setTimeout(()=>{closeOverlay('Settings');loadAudioProfiles();},1000);
|
||||
setTimeout(()=>{closeOverlay('Settings');loadAudioParams();},1000);
|
||||
}catch(e){toast('Failed: '+e.message);}
|
||||
};
|
||||
document.getElementById('btnRestartSvc').onclick=()=>{toast('Restarting service...');fetch('/api/settings',{method:'POST',body:JSON.stringify({_restart:true})}).catch(()=>{});};
|
||||
|
||||
Reference in New Issue
Block a user