FIX: 3 bugs - soundfont engine fallback, media explorer icons/drag, carla midi playback routing
- render_engine: soundfont track không có plugin_id giờ vẫn dùng instrument sf2 thay vì rơi về wave synth - fontawesome: sửa đường dẫn webfonts (bỏ ../) hết 404 icon - media explorer: drag MIDI library items vào timeline tạo được midi item (sinh 6 MIDI loop mẫu + resolve drop file) - app.jsx: 3 path gate window.SonicSF cho phép route playback qua SonicCarlaMidi
This commit is contained in:
+11
-4
@@ -21306,13 +21306,13 @@ const App = () => {
|
||||
|
||||
// MIDI items playback
|
||||
const midiItems = track.midiItems || [];
|
||||
if ((track.type === 'MIDI' || midiItems.length > 0) && window.SonicSF) {
|
||||
if ((track.type === 'MIDI' || midiItems.length > 0) && (window.SonicSF || (window.SonicCarlaMidi && window.SonicCarlaMidi.shouldRoutePlayback(track.synth_engine)))) {
|
||||
// Preview cache: capture the soundfont (pre track-FX) for fast offline export
|
||||
ensureMidiCapture(track, activeTrackNodesRef.current[track.id]);
|
||||
if (window.SonicCarlaMidi && window.SonicCarlaMidi.shouldRoutePlayback(track.synth_engine)) ensureCarlaForPlayback(track.synth_engine);
|
||||
var trkCh = assignTrackMidiChannel(track, allPlayTracks);
|
||||
// Ensure instrument is loaded in FluidSynth
|
||||
if (track.synth_engine && track.synth_engine.type === 'soundfont' && track.synth_engine.soundfont_id) {
|
||||
if (window.SonicSF && track.synth_engine && track.synth_engine.type === 'soundfont' && track.synth_engine.soundfont_id) {
|
||||
window.SonicSF.selectInstrument(trkCh, track.synth_engine.soundfont_bank || 0, track.synth_engine.soundfont_program || 0, track.synth_engine.soundfont_id);
|
||||
}
|
||||
const bpmVal = parseInt(bpm) || 120;
|
||||
@@ -21464,7 +21464,7 @@ const App = () => {
|
||||
|
||||
// 2. Play MIDI items in subTrack
|
||||
const subMidiItems = subTrack.midiItems || [];
|
||||
if (window.SonicSF && subMidiItems.length > 0) {
|
||||
if (subMidiItems.length > 0 && (window.SonicSF || (window.SonicCarlaMidi && window.SonicCarlaMidi.shouldRoutePlayback(subTrack.synth_engine)))) {
|
||||
subMidiItems.forEach(item => {
|
||||
const notes = item.notes || [];
|
||||
notes.forEach(note => {
|
||||
@@ -21592,7 +21592,7 @@ const App = () => {
|
||||
|
||||
// MIDI items playback
|
||||
const midiItems = track.midiItems || [];
|
||||
if ((track.type === 'MIDI' || midiItems.length > 0) && window.SonicSF) {
|
||||
if ((track.type === 'MIDI' || midiItems.length > 0) && (window.SonicSF || (window.SonicCarlaMidi && window.SonicCarlaMidi.shouldRoutePlayback(track.synth_engine)))) {
|
||||
var lcCh = assignTrackMidiChannel(track, tracks);
|
||||
const bpmVal = parseInt(bpm) || 120;
|
||||
const secondsPerBeat = 60.0 / bpmVal;
|
||||
@@ -23905,6 +23905,13 @@ const App = () => {
|
||||
const blob = await resp.blob();
|
||||
return new File([blob], mef.name || mef.path.split(/[\\/]/).pop(), { type: blob.type || 'application/octet-stream' });
|
||||
}
|
||||
// Media Library samples: only metadata (name/kind) — real bytes served
|
||||
// from /static/midi (generated demo loops, see app/static/midi).
|
||||
if (mef.kind === 'midi' && mef.name) {
|
||||
const resp = await fetch(`${API_BASE_URL}/static/midi/${encodeURIComponent(mef.name)}`);
|
||||
const blob = await resp.blob();
|
||||
return new File([blob], mef.name, { type: 'audio/midi' });
|
||||
}
|
||||
} catch (e) {
|
||||
showToast('Không thể nạp file từ Media Explorer: ' + e.message, 'error');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user