perf: slim daw_engine bundle 409MB->170MB + fix engine khong chay tren Windows

- Thay librosa bang app/core/audio_features.py (numpy/scipy/soundfile):
  load, beat_track, frames_to_time, spectral_centroid, rms, zero_crossing_rate,
  time_stretch, pitch_shift, chroma_stft. A/B ngang librosa (BPM <1% sai lech,
  pitch_shift chuan toi Hz). Loai bo llvmlite 171MB + scikit-learn + numba.
- Task layer 2 che do (app/tasks/worker.py): server giu celery; desktop slim
  chay in-process thread + registry, giu nguyen API contract (.delay/.id/status
  /tasks/{id}) nen frontend khong doi.
- engine.spec: excludes librosa/numba/llvmlite/sklearn/celery/redis/kombu/
  billiard/amqp/msgpack/yaml/PIL/cairosvg/zstandard/...; scan scipy gioi han
  scipy.signal; giu click (uvicorn.main import click).
- render_engine: scipy.signal thanh lazy import (giam cold start).
- tauri.conf.json: targets [nsis, msi] - NSIS tro lai (bundle nho) de
  hooks.nsh cai VC++ Redistributable - sua bug daw_engine.exe khong chay
  tren Windows (truoc day MSI-only khong chay hooks).
- build_linux.sh / build_macos.sh: build 1 lenh moi OS.
- Doc: DESKTOP_INSTALL_PLAN.md muc 5.1.
- Verify: 86 tests pass, engine dong goi upload/analyze/waveform/export OK.
This commit is contained in:
2026-08-09 10:17:10 +00:00
parent 1191e46ee5
commit 29ebbfc1c0
13 changed files with 746 additions and 123 deletions
+21 -12
View File
@@ -1,19 +1,28 @@
import os
import json
import librosa
import numpy as np
from typing import Optional
# Thay librosa bang shim nhe (numpy/scipy/soundfile) — khong keo numba/llvmlite
from app.core.audio_features import (
load as _load,
beat_track as _beat_track,
frames_to_time as _frames_to_time,
spectral_centroid as _spectral_centroid,
rms as _rms,
zero_crossing_rate as _zcr,
)
def analyze_audio(file_path: str) -> dict:
"""
Phân tích âm thanh: BPM, beat tracking, ước lượng bars.
"""
# Load audio
y, sr = librosa.load(file_path, sr=None)
y, sr = _load(file_path, sr=None)
# Track beats
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
tempo, beat_frames = _beat_track(y=y, sr=sr)
# Handle tempo which might be scalar or numpy array in different librosa versions
if isinstance(tempo, np.ndarray):
@@ -25,7 +34,7 @@ def analyze_audio(file_path: str) -> dict:
bpm = float(tempo)
# Convert frames to time (seconds)
beat_times = librosa.frames_to_time(beat_frames, sr=sr).tolist()
beat_times = _frames_to_time(beat_frames, sr=sr).tolist()
# Estimate bars (assume 4/4 time signature - grouping every 4 beats)
bar_times = [beat_times[i] for i in range(0, len(beat_times), 4)]
@@ -43,31 +52,31 @@ def analyze_audio_advanced(file_path: str) -> dict:
Phân tích âm thanh nâng cao: BPM, beats, bars, spectral features.
Sử dụng librosa để trích xuất đặc trưng âm học chi tiết.
"""
y, sr = librosa.load(file_path, sr=None)
y, sr = _load(file_path, sr=None)
duration = float(len(y)) / sr
# Beat tracking
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
tempo, beat_frames = _beat_track(y=y, sr=sr)
if isinstance(tempo, np.ndarray):
bpm = float(tempo[0]) if tempo.size > 0 else 120.0
else:
bpm = float(tempo)
beat_times = librosa.frames_to_time(beat_frames, sr=sr).tolist()
beat_times = _frames_to_time(beat_frames, sr=sr).tolist()
bar_times = [beat_times[i] for i in range(0, len(beat_times), 4)]
# Spectral centroid (brightness)
spectral_centroids = librosa.feature.spectral_centroid(y=y, sr=sr)[0]
spectral_centroids = _spectral_centroid(y=y, sr=sr)[0]
avg_brightness = float(np.mean(spectral_centroids))
# RMS energy
rms = librosa.feature.rms(y=y)[0]
avg_energy = float(np.mean(rms))
rms_vals = _rms(y=y)[0]
avg_energy = float(np.mean(rms_vals))
# Zero crossing rate
zcr = librosa.feature.zero_crossing_rate(y)[0]
avg_zcr = float(np.mean(zcr))
zcr_vals = _zcr(y)[0]
avg_zcr = float(np.mean(zcr_vals))
return {
"bpm": round(bpm, 2),