Files
SonicForgeStudio/app/static/js/services/runtime.js
T

93 lines
4.3 KiB
JavaScript

// SonicForge Runtime service — phát hiện môi trường chạy (desktop Windows /
// docker headless) qua /api/v1/system/capabilities, bật/tắt tính năng theo đó.
// - data-runtime trên <html>: "desktop" | "headless"
// - data-carla="1": có Carla local (hiện nút "Mở trong Carla")
// - Phần tử có thuộc tính data-carla-only sẽ bị ẩn khi không có Carla local.
// - Thư viện preset (.vstpreset) cache trong SonicRuntime.presets — dùng cho
// dropdown gán preset vào track (Carla → pedalboard bridge).
window.SonicRuntime = window.SonicRuntime || { loaded: false, capabilities: null, presets: null };
(function () {
function getHeaders() {
const token = localStorage.getItem('sonic_token') || '';
return token ? { 'Authorization': 'Bearer ' + token } : {};
}
function load() {
return fetch(window.API_BASE_URL + '/api/v1/system/capabilities')
.then(function (r) { return r.json(); })
.then(function (data) {
var c = data && data.success ? data : { features: {} };
window.SonicRuntime.capabilities = c;
window.SonicRuntime.loaded = true;
var html = document.documentElement;
html.dataset.runtime = c.runtime || 'unknown';
html.dataset.platform = c.platform || '';
html.dataset.carla = (c.features && c.features.carla_local) ? '1' : '0';
if (c.features && c.features.carla_local === false) {
document.querySelectorAll('[data-carla-only]').forEach(function (el) {
el.style.display = 'none';
});
}
// Cache sẵn danh sách preset (static, ít thay đổi)
listPresets().catch(function () {});
return c;
})
.catch(function () { return null; });
}
function listPresets() {
if (window.SonicRuntime.presets) return Promise.resolve(window.SonicRuntime.presets);
return fetch(window.API_BASE_URL + '/api/v1/presets', { headers: getHeaders() })
.then(function (r) { return r.json(); })
.then(function (d) {
window.SonicRuntime.presets = (d && d.presets) || [];
return window.SonicRuntime.presets;
})
.catch(function () { return []; });
}
window.SonicRuntime.load = load;
window.SonicRuntime.listPresets = listPresets;
window.SonicRuntime.refreshPresets = function () {
window.SonicRuntime.presets = null;
return window.SonicRuntime.listPresets();
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', load);
} else {
load();
}
})();
// ── SonicCarlaMidi: cầu nối MIDI từ track ARM → Carla (OSC /Carla/0/note_*) ──
// Khi track dùng VSTi (synth_engine.type chứa 'vst') + được ARM + máy có Carla
// local → phím bấm trên piano roll / keybed được gửi tới Carla để phát realtime
// (Carla standalone bật OSC UDP mặc định cổng 22752).
window.SonicCarlaMidi = window.SonicCarlaMidi || {
shouldRoute: function (synthEngine, isArmed) {
try {
var c = window.SonicRuntime && window.SonicRuntime.capabilities;
if (!c || !c.features || !c.features.carla_local) return false;
if (!isArmed) return false;
var se = synthEngine || {};
return String(se.type || '').indexOf('vst') !== -1 && !!se.plugin_id;
} catch (e) { return false; }
},
noteOn: function (channel, note, velocity) {
if (!window.SonicAPI || !window.SonicAPI.carlaMidi) return;
window.SonicAPI.carlaMidi({ event: 'note_on', note: note, velocity: velocity || 100, channel: channel || 0 }).catch(function () {});
},
noteOff: function (channel, note) {
if (!window.SonicAPI || !window.SonicAPI.carlaMidi) return;
window.SonicAPI.carlaMidi({ event: 'note_off', note: note, channel: channel || 0 }).catch(function () {});
},
// Bật note rồi tự tắt sau durMs (preview ngắn)
playNote: function (channel, note, velocity, durMs) {
this.noteOn(channel, note, velocity);
var self = this;
setTimeout(function () { self.noteOff(channel, note); }, (durMs || 300) + 50);
}
};