fix(midi): route MIDI live via masterBus, fix media explorer drag, add action logging
- TrackInstrument: gate native live path (SF/VSTi WASAPI bridge bypassed masterBus -> mastering FX + main out VU dead). Fallback to SonicSF WASM through masterBus.input; native kept for offline render only. - MEDIA_LIBRARY_SAMPLES: rename MIDI_Loop_02_Bass/03_Lead/05_Bass to match actual /static/midi files (drag was 404 -> parse error). - Add SonicAppLogger (console + POST /api/v1/logs) wired to: instrument load error, VSTi autosample fail, MIDI item -> mastering fx chain, play -> main out, drag MIDI errors (media explorer + window explorer). - Add backend /api/v1/logs endpoint (server-side log, no DB).
This commit is contained in:
+21
-5
@@ -6284,7 +6284,9 @@ const preloadTrackInstruments = async (tracks) => {
|
||||
const ch = t.midiChannel !== undefined ? t.midiChannel : (i % 16);
|
||||
try {
|
||||
await window.SonicSF.selectInstrument(ch, bank, prog, sfId);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('INSTRUMENT', 'Load instrument fail', { track: t.name, sfId: sfId, bank: bank, prog: prog, err: e && e.message }); } catch (e2) {}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13203,10 +13205,10 @@ const MasteringModal = ({ isOpen, onClose, masteringSettings, setMasteringSettin
|
||||
// ── Media Explorer Panel (from md/51_MEDIA_EXPLORER.md) ──
|
||||
const MEDIA_LIBRARY_SAMPLES = [
|
||||
{ name: "MIDI_Loop_01.mid", events: 95, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_02_Bass.mid", events: 48, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_03_Lead.mid", events: 110, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_02.mid", events: 48, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_03.mid", events: 110, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_04.mid", events: 76, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_05_Bass.mid", events: 52, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_05.mid", events: 52, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" },
|
||||
{ name: "MIDI_Loop_06.mid", events: 88, lengthQn: 16, time: "0:08.000", tpqn: 480, bpm: 130, kind: "midi" }
|
||||
];
|
||||
|
||||
@@ -15592,7 +15594,10 @@ const App = () => {
|
||||
window.SonicVstiAutosample.ensure(_warmEngine).then(_sfId => {
|
||||
if (!_sfId && window.SonicVstiAutosample.failReasonFor) {
|
||||
const _reason = window.SonicVstiAutosample.failReasonFor(_warmEngine);
|
||||
if (_reason && window.showToast) window.showToast('Autosample VSTi that bai: ' + _reason + ' - dung am default', 'warning');
|
||||
if (_reason) {
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('VSTI', 'Autosample VSTi fail', { plugin_id: instrumentId, reason: _reason }); } catch (e2) {}
|
||||
if (window.showToast) window.showToast('Autosample VSTi that bai: ' + _reason + ' - dung am default', 'warning');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -21879,6 +21884,11 @@ const App = () => {
|
||||
const routeCarla = shouldRouteCarla(track.synth_engine);
|
||||
const nativeSf = isStandaloneSf() && !routeCarla && isSfTrackEngine(track.synth_engine);
|
||||
if ((track.type === 'MIDI' || midiItems.length > 0) && (window.SonicSF || routeCarla || nativeSf)) {
|
||||
try {
|
||||
const _mActive = !!(masterBus && masterBus.masteringActive);
|
||||
window.SonicAppLogger && window.SonicAppLogger.info('MIDI_ITEM', nativeSf ? 'render_offline_native -> WAV -> mastering fx chain' : 'WASM -> masterBus.input -> mastering fx chain', { track: track.id, name: track.name, items: midiItems.length, masteringActive: _mActive, nativeSf: !!nativeSf });
|
||||
window.SonicAppLogger && window.SonicAppLogger.info('MIDI_ITEM', 'play_qua_main_out', { track: track.id, name: track.name, items: midiItems.length, dest: 'masterBus.analyser -> ctx.destination' });
|
||||
} catch (e2) {}
|
||||
if (nativeSf) {
|
||||
midiItems.forEach(item => scheduleNativeSfItem(track, item, offsetTime, context, gainNode, bpm, { sources: activeSourcesRef.current, isActive: () => !!isPlayingRef.current }));
|
||||
} else {
|
||||
@@ -24540,9 +24550,11 @@ const App = () => {
|
||||
return new File([blob], mef.name, { type: 'audio/midi' });
|
||||
}
|
||||
} catch (e) {
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('DRAG_MIDI', 'Media Explorer drag resolve fail', { name: mef && mef.name, kind: mef && mef.kind, err: e && e.message }); } catch (e2) {}
|
||||
showToast('Không thể nạp file từ Media Explorer: ' + e.message, 'error');
|
||||
return null;
|
||||
}
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('DRAG_MIDI', 'Media Explorer drag missing file data', { name: mef && mef.name, kind: mef && mef.kind }); } catch (e2) {}
|
||||
showToast('Không thể nạp file từ Media Explorer: thiếu dữ liệu file.', 'error');
|
||||
return null;
|
||||
};
|
||||
@@ -24557,6 +24569,7 @@ const App = () => {
|
||||
var arrayBuffer = await file.arrayBuffer();
|
||||
var midiResult = parseMidiFile(arrayBuffer);
|
||||
if (!midiResult || midiResult.length === 0) {
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('DRAG_MIDI', 'Window explorer drag parse empty', { name: fileName, size: file.size }); } catch (e2) {}
|
||||
showToast('Không tìm thấy nốt nhạc trong file MIDI.', 'error');
|
||||
return;
|
||||
}
|
||||
@@ -24612,6 +24625,7 @@ const App = () => {
|
||||
} : t));
|
||||
showToast(`Nạp file thành công: ${fileName} (${channelInfo.label})`, 'success');
|
||||
} catch (err) {
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('DRAG_MIDI', 'Window explorer drag load fail', { name: fileName, isMidi: isMidi, err: err && err.message }); } catch (e2) {}
|
||||
showToast(isMidi ? "Lỗi giải mã MIDI." : "Lỗi giải mã âm thanh. Định dạng file không tương thích.", 'error');
|
||||
}
|
||||
};
|
||||
@@ -24624,6 +24638,7 @@ const App = () => {
|
||||
var arrayBuffer = await file.arrayBuffer();
|
||||
var midiResult = parseMidiFile(arrayBuffer);
|
||||
if (!midiResult || midiResult.length === 0) {
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('DRAG_MIDI', 'Drag MIDI parse empty', { name: file && file.name, size: file && file.size }); } catch (e2) {}
|
||||
showToast('Không tìm thấy nốt nhạc trong file MIDI.', 'error');
|
||||
return;
|
||||
}
|
||||
@@ -24645,6 +24660,7 @@ const App = () => {
|
||||
if (newTracks.length > 0) setSelectedTrackId(newTracks[0].id);
|
||||
showToast('Đã tải MIDI: ' + newTracks.length + ' track(s) từ ' + file.name, 'success');
|
||||
} catch (err) {
|
||||
try { window.SonicAppLogger && window.SonicAppLogger.error('DRAG_MIDI', 'Drag MIDI decode fail', { name: file && file.name, err: err && err.message }); } catch (e2) {}
|
||||
showToast('Lỗi giải mã MIDI.', 'error');
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user