78 lines
3.4 KiB
JavaScript
78 lines
3.4 KiB
JavaScript
// SonicForge Native Audio Client (T15) — IPC JS → native engine.
|
|
// Track instrument KHÔNG còn đi masterBus WebAudio: master fader + track
|
|
// gain/pan áp native qua NativeMixer (SF host / VST2 / VST3 bridge DLL).
|
|
// WebAudio chỉ giữ cho UI/aux. Mọi call fire-and-forget — native engine
|
|
// tự âm thanh; không block UI.
|
|
window.SonicNativeAudio = window.SonicNativeAudio || {};
|
|
|
|
(function () {
|
|
var BASE = window.API_BASE_URL || window.location.origin;
|
|
|
|
function headers() {
|
|
var h = { 'Content-Type': 'application/json' };
|
|
var token = localStorage.getItem('sonic_token') || '';
|
|
if (token) h['Authorization'] = 'Bearer ' + token;
|
|
return h;
|
|
}
|
|
|
|
async function post(path, body) {
|
|
var resp = await fetch(BASE + '/api/v1/native' + path, {
|
|
method: 'POST',
|
|
headers: headers(),
|
|
body: JSON.stringify(body || {})
|
|
});
|
|
var data = await resp.json().catch(function () { return {}; });
|
|
if (!resp.ok) throw new Error(data.detail || 'native API lỗi ' + resp.status);
|
|
return data;
|
|
}
|
|
|
|
async function get(path) {
|
|
var resp = await fetch(BASE + '/api/v1/native' + path, { headers: headers() });
|
|
var data = await resp.json().catch(function () { return {}; });
|
|
if (!resp.ok) throw new Error(data.detail || 'native API lỗi ' + resp.status);
|
|
return data;
|
|
}
|
|
|
|
var _masterTimer = null;
|
|
|
|
window.SonicNativeAudio = {
|
|
status: function () {
|
|
return get('/status');
|
|
},
|
|
// Master fader: debounce 40ms — fader kéo liên tục, chỉ gửi giá trị cuối.
|
|
setMasterGain: function (gainDb) {
|
|
if (_masterTimer) clearTimeout(_masterTimer);
|
|
_masterTimer = setTimeout(function () {
|
|
post('/set_master_gain', { gain_db: gainDb }).catch(function (e) {
|
|
console.warn('[NativeAudio] set_master_gain:', e.message);
|
|
});
|
|
}, 40);
|
|
},
|
|
setTrackGainPan: function (trackId, gainDb, pan) {
|
|
return post('/track_gain_pan', { track_id: trackId, gain_db: gainDb, pan: pan }).catch(function (e) {
|
|
console.warn('[NativeAudio] track_gain_pan:', e.message);
|
|
});
|
|
},
|
|
ensureSf: function (trackId, sfId, bank, program) {
|
|
return post('/sf/ensure', { track_id: trackId, sf_id: sfId || null, bank: bank || 0, program: program || 0, live: true }).catch(function (e) {
|
|
console.warn('[NativeAudio] sf/ensure:', e.message);
|
|
});
|
|
},
|
|
noteOn: function (kind, trackId, channel, pitch, velocity) {
|
|
var path = kind === 'vst2' ? '/vst2/note_on' : '/sf/note_on';
|
|
return post(path, { track_id: trackId, channel: channel || 0, pitch: pitch, velocity: velocity != null ? velocity : 100 }).catch(function (e) {
|
|
console.warn('[NativeAudio] note_on:', e.message);
|
|
});
|
|
},
|
|
noteOff: function (kind, trackId, channel, pitch) {
|
|
var path = kind === 'vst2' ? '/vst2/note_off' : '/sf/note_off';
|
|
return post(path, { track_id: trackId, channel: channel || 0, pitch: pitch }).catch(function (e) {
|
|
console.warn('[NativeAudio] note_off:', e.message);
|
|
});
|
|
},
|
|
sfAudioStop: function (trackId) {
|
|
return post('/sf/audio_stop', { track_id: trackId, pitch: 0 }).catch(function () {});
|
|
}
|
|
};
|
|
})();
|