An electron app for using soulx-singer SVS with directml GPU support and user-friendly Ui.
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
Add sxseditor MCP server to project-level client config | 1 个月前 | |
refactor(splash): 启动画面改用 BaseWindow + ImageView 位图,移除 HTML 渲染路径 启动画面此前是「内联 SVG + <text> 的静态 HTML」,首帧成本里仍含字体匹配与 字形 shaping(且仍要起一个渲染进程)。改为在主进程内直接绘制: - src/main/splashManager.js 重写为 new BaseWindow() + new ImageView(), nativeImage 两个 representation(2x/3x)挂同一个对象,各屏各取 1:1 位图; - scripts/generate-splash-image.js(新增,@napi-rs/canvas devDep)在构建期把 版面/亚克力卡片/版本号/构建时间烘进 PNG,src/splash@2x.png、@3x.png 为 构建产物(.gitignore),由 prestart / prepackage 生成; - scripts/generate-build-info.js 输出 buildDateDisplay / utcOffset / channel / buildYear 供位图直接拼接,不再做模板占位符替换;CI 在 release 分支导出 SXS_CHANNEL=stable,其余一律 Nightly; - webpack.main.config.js CopyPlugin 逐字拷两张 PNG 到 .webpack/main/, verify-build-assets.js 改为校验生成器(产物在其后才生成); - 删除 src/splash.html.template,src/preload.js 注释去掉 splash 窗口; - ImageView 属实验 API:类缺失或位图读不到时降级为「不显示启动画面」, 绝不阻断启动(test/splashAssets.test.js 守这条及窗口尺寸/倍率/CopyPlugin)。 窗口 480×272 transparent + hasShadow:false(圆角靠 per-pixel alpha), 尺寸必须等于生成器的 LOGICAL_W/H,否则 ImageView 会拉伸。 | 6 天前 | |
perf+quality: SVS inference review (batch merge, WSOLA, CFG schedule, loudnorm, STORK-2) (#25) * spec: add SVS inference perf & quality review spec * perf+quality: apply SVS inference review (WSOLA, loudnorm, F0 linear, anti-aliasing, adaptive GPU drain) Phase C implementation (Tasks 1-10, 12, 13, 16): P0 performance: - DML cond/uncond batch merge: single session.run for CFG (diffusion.js) - Diagnostic log gating behind diagnosticMode setting (default false) - releaseDiffStepBeforeVocoder default false + OOM dynamic enable - Default sampler Euler -> STORK-2 P1 performance & quality: - VOCODER_OVERLAP_FRAMES 8 -> 32 + user-adjustable setting (8-96) - Per-step xt/t tensor pre-allocation reuse in diffusion loop - CFG combine three-pass -> single-pass Welford online variance - Adaptive gpuDrain: skip 50ms wait normally, 200ms after OOM - WSOLA crossfade replacing Hann OLA (vocoder + diffusion chunk boundaries) - EBU R128 loudnorm (-14 LUFS) + true-peak limiter (-1 dBTP) - CFG rescale default 0.75 -> 0.6 with UI range warning P2 quality: - SiFiGAN F0 4x upsampling: nearest-neighbor -> linear interpolation - Anti-aliasing Butterworth LP filter before decimation (opt-in, default false) New files: wsola.js, loudnorm.js New tests: wsola, loudnorm, gpuDrainAdaptive, diffusionBatchMerge, cfgCombineWelford All 1413 tests passing, no new lint errors. * perf+quality: Task 14+15 refHash FNV-1a full-length and F0-aware chunking Task 14: Replace partial (first 4000 bytes + stride) polynomial scan in audioSegmentation.computeSynthCacheKey with full-length FNV-1a via hashArray. Normalizes ArrayBuffer / TypedArray / Buffer / plain array inputs. Eliminates false cache hits on long reference audio where two buffers share only the first 4000 bytes. Added determinism + divergence tests. Task 15: Add optional f0Slope parameter to diffusion._planChunks. When provided, searches [chunkStart+minBeats, chunkStart+maxBeats] for the boundary with smallest |f0Slope[boundary]|, avoiding F0 slope discontinuities (vibrato onset/offset, note transitions). Falls back to fixed safeChunk when f0Slope is null or too short (no behavior change). runDiffusionLoopChunked accepts pitchCurveF0, computes per-frame F0 slope (f0[i+1]-f0[i]) and passes to _planChunks. pipeline/index.js threads sequences.f0Hz through _currentPitchCurveF0. Task 17 (partial): Add enableSDEditRepair setting (default false) to settings.js. Repair logic in diffusion.js runDiffusionLoop follows. * perf+quality: Task 11+17+18 CFG schedule, SDEdit repair, UI integration - Task 11: Add cfgSchedule.js with resolveCfgAtStep supporting constant/linear/cosine/custom modes. constant mode returns cfgStrength directly (byte-identical to pre-Task-11). Integrate step-aware CFG into diffusion combine via cfgScheduleOpts threading through pipeline/index.js and audioPlayback.js. - Task 17: Add _sdeditRepair in diffusion.js for local mel anomaly detection (NaN/energy spikes) and shallow-noise re-sampling repair. Gated by enableSDEditRepair setting (default false, zero overhead). - Task 18: Add i18n labels (en.js + zh-CN.js) for all new controls, exportDialog.js UI for CFG schedule mode/start/keyframes, vocoder overlap, loudnorm/anti-alias/SDEdit/diagnostic toggles, and settingsToSave for all new keys. - Fix streamingSynthesis.test.js assertion for new trailing params (pitchCurveF0, cfgScheduleOpts) in runDiffusionLoopChunked. * spec: mark Task 11/14/15/17/18/19 complete in tasks.md and checklist.md * fix(review): address PR #25 review issues (B1, B2, M1-M12, N1-N5) BLOCKER: - B1: cfgScheduleKeyframes field name mismatch (index.js output key → keyframes) - B2: cfgRescaleRangeWarn i18n key added to main.exportDialog namespace MAJOR: - M1: WebNN path now applies CFG schedule (resolveCfgAtStep threaded + used) - M3: SDEdit repair combine accepts stepOverride/totalStepsOverride (no stale currentStep) - M4: releaseDiffStepBeforeVocoder i18n updated (on -> off by default) - M5: Preview CFG schedule UI added (mirrors export via buildCfgScheduleField helper) - M6: Default sampler fallback unified to DEFAULT_SOLVER (no more || 'euler') - M7: Single-chunk vocoder loudnorm reordered (streaming gets peak-norm, final gets loudnorm) - M8: cfgCombineWelford.test.js strengthened with 24-seed sweep + edge cases + limitation doc - M9: loudnorm.test.js disabled-path contract test added + misleading test renamed - M10: streamingSynthesis.test.js asserts pitchCurveF0 + cfgScheduleOpts passthrough - M11: cfgSchedule.test.js keyframe parsing edge cases (invalid entries, NaN, duplicates) - M12: cfgStrengthStart input clamped to [0,10]; cfgSchedule.js return values clamped >= 0 NIT: - N1: wsola.js JSDoc updated to describe global single-offset alignment - N2: fadeWindow dead code removed from diffusion.js _planChunks - N3: WebNN double .slice() retained (outputToFloat32 returns view for float32 - slice required) - N4: loudnorm.js true-peak comment clarifies 4x linear interp vs ITU BS.1770 FIR - N5: Keyframe hint example uses step 31 (matches default 32-step diffusion) Tests: 1448 passing, 0 failing. Lint: 0 new errors in modified files. --------- Co-authored-by: Trae Bot <trae-bot@local> | 2 个月前 | |
backup: WIP splash-screen feature before min-duration tweak (issue splash-screen-feature, prep) | 3 个月前 | |
feat: add FP16 quantization pipeline with full Olive optimization and post-process type fix Add complete FP16 re-quantization pipeline for all 9 ONNX models: 1. generate_fp16_calibration.py: Self-calibration data generator using FP32 ONNX models as reference. Generates diverse inputs covering all model inputs with deterministic seed for reproducibility. 2. convert_fp16_w16a32.py: W16A32 (FP16 weights + FP32 activations) converter with full Olive DML optimization (OnnxQuantizationPreprocess + OnnxPeepholeOptimizer with all passes enabled). Uses inlined resolve_neg1_in_reshape_shapes to avoid heavy imports from export_shared. 3. quantize_fp16_true.py: True FP16 (FP16 weights + activations) quantizer using onnxconverter_common convert_float_to_float16 + Olive DML optimization. 4. fix_diff_step_olive_postproc.py: Post-process type mismatch fixer for diff_step_dml. Root cause: Olive onnxscript_optimize pass removes Cast(FP16 to FP32) nodes in W16A32 (treating them as redundant) but does not update weight initializer dtype, leaving MatMul with mismatched FP32/FP16 inputs. Fix: run FULL Olive optimization, then post-process to re-insert deleted Cast nodes. This preserves all Olive benefits (node fusion, dead code elimination, reshape fusion) while restoring type safety. For TrueFP16, also fixes Cast(INT64 to FP32) that onnxconverter_common misses by updating both the to attribute and corresponding value_info. 5. compare_fp16_variants.py: Precision comparison script running FP32 vs W16A32 vs TrueFP16 vs BackupFP16 on DML backend, using identical random inputs across all variants. Reports cosine similarity, SNR, MSE, max diff. Precision results (vs FP32 baseline on DML): - W16A32: all 9 models EXCELLENT (cos>0.9999, snr>40dB) - TrueFP16: 7/9 EXCELLENT; mel_transform BROKEN (STFT sensitive), vocoder_dml BROKEN (ISTFT sensitive) - diff_step_dml W16A32: cos=0.99999999, snr=78.02 dB - diff_step_dml TrueFP16: cos=0.99999448, snr=49.32 dB Update .gitignore to exclude large FP16 model/calibration/comparison files. Update docs/dev/onnx-models.html with Olive post-process type fix documentation. | 3 个月前 | |
fix(landing): point singer-market entries at the live market site The homepage linked every "go to the singer market" action (the two singer cards' "View in Market" buttons, the "Browse Singer Market" CTA and the footer link) at the user-guide page instead of the actual marketplace. Only app-usage links (import instructions / create your own singer) should resolve to the docs. All market entries now open https://singer-files.15240287482.workers.dev/explore in a new tab. | 19 小时前 | |
backup: before adding vocoder output explosion diagnostics | 3 个月前 | |
ci: add release CI with Inno Setup packaging and rolling releases (issue release-ci-pipeline) | 3 个月前 | |
feat(intro-video): real-inference promo scenes + reproducible asset pipeline - intro-video: 新增 RealInferenceScene / SpecsScene,展示一次真实 SVS 推理 的输入(钢琴卷帘 + 中文唱词)与输出(梅尔频谱 / 波形 / 实测指标), 成片 30s @ 1920x1080/30fps,音频轨即真实推理输出 - scripts/intro-video-assets.js: 调用 OnnxSVSPipeline 在 CPU EP 上跑真实 推理(32 步扩散),产出 sample.wav 与 metrics.json,可复现 - scripts/intro-video-spectrogram.py: 从真实 WAV 计算梅尔频谱图 / 波形图 / RMS 包络,供宣传片动画使用 - forge.config.js: 修复 Linux deb/rpm 打包 —— electron-installer-debian 默认按 package.json 的 name(sxseditor) 找二进制,而 packager 产出的是 productName(SXSEditor),导致 make 直接失败;显式指定 bin 并补 maintainer/homepage。已在 Linux x64 实测产出 sxseditor_2.0.2_amd64.deb - .gitignore: intro-video 生成物交由子 .gitignore 管理,样例 WAV 加例外 | 2 天前 | |
fix(ci): align native addon marker check with d2h-copy-v3 fallback Commit 5320714 bumped the ort_bridge build tag from d2h-copy-v2 to v3 (the D2H ArrayBuffer fallback), but ci.yml still asserted the binary contained the v2 marker. Every push since then failed the Test job at the prebuilt-sync verification, which in turn skipped the release build. Update all three marker checks to v3 and refresh the tracked prebuilt addon to match the freshly built v3 binary. | 1 个月前 | |
test(preprocess): add RMVPE end-to-end harness, require fixed model versions The RMVPE regression only showed up end-to-end: the old model loaded fine and returned numbers, they were just all 30 Hz. Unit tests on decode logic would not have caught it, so add a harness that drives the real detector against the real ModelScope artifacts and asserts against ground truth. - test/e2e/rmvpeE2E.js: synthesizes a known melody (MIDI 60/62/64/62/67/64/60 @96BPM, 24 kHz, 0.5 s silence at both ends), runs extractF0, and checks median/p95 cents error, silence false positives, 30 Hz-stuck frames and NaNs. Runs under plain node or under Electron ( xvfb-run npx electron test/e2e/rmvpeE2E.js), so the exact runtime that ships on Linux is verified. - package.json: npm run test:e2e:rmvpe (node; --model label=path for other artifacts). - README: state the minimum model version per ModelScope repo (directml v2, fp16 v3, int8 v1, int8-dynamic v1) and that older RMVPE models are incompatible with this code and must be upgraded. | 1 天前 | |
feat: 应用 SXSEditor-full.patch(33 项审查修复 + 插件系统) 应用交付说明 SXSEditor-full.patch(基线 392cf62,94 文件,+8107/-502)。 主要内容: - 暂停按钮图标消失:新增 iconHelper.setLabel(),只写文本节点保留已注入的 SVG; 24 处 textContent 赋值改为 setLabel;applyLocale 改 appendChild。 - 审查报告 33 项(F-01…F-33)修复,含路径授权 realpath+8.3+denylist、 IPC 错误统一脱敏(新增 src/main/ipcSafe.js)、sandbox:true、模型清单、 i18n 补键、版本号统一为 app.getVersion() 等。 - 新增插件系统:pluginContract / pluginHost / pluginWorker / pluginIpc / pluginBackend / pluginTrackDialog / pluginBlockingOverlay / pluginEditorMode, 外加 plugins/example-concat 示例与 docs/dev/plugins.md。 本 commit 仅做原样应用;针对该 patch 的两处回归修复与瘦身改动见上一 commit。 | 18 天前 | |
feat: add PyTorch FP16 mixed-precision quantization with calibration for SoulX-Singer Quantize SoulX-Singer PyTorch model to FP16 mixed precision using weight-analysis calibration with GTSinger mel data. Only mel module (MelSpectrogramEncoder) stays FP32 (STFT+log+sqrt precision-critical); all other 584 params convert to FP16. Results (2.00x compression, 2687MB -> 1344MB): - Weight-level: SNR=73.65dB, cos=1.0001, L0=0/704M (0.00%) - Vocoder activation: SNR=43.57dB, cos=0.99998, L0=1.88% - CFM decoder activation: SNR=56.98dB, cos=0.99999, L0=1.25% - Preflow activation: SNR=64.43dB, cos=1.00000, L0=0.00% - Embeddings: SNR=73.65dB, cos=1.00000, L0=0.00% Phase 2 activation verification bypasses slow librosa numba JIT by mocking librosa.filters.mel (mel_basis is overwritten by state_dict anyway). | 3 个月前 | |
chore(qdrift): recalibrate fp16 correction on rest-fixed conditions The <SP> rest-encoding fix changed noteType and f0 sequences for all gap rests, so previous conditions and calibration were stale. Re-exported all 38 prj conditions (stale manifest segment entries pruned), reran full calibration: 46 items (8 nat + 38 prj) x 3 seeds = 138 trajectories on the DML runtime matching the app. Regenerated qdriftCorrection.js and eval report. Eval (seed 1234, 4 items incl. rest-dense xinzuo/lagtrain/monitoring): mel cosine B/C vs A >= 0.99999, SNR >= 45 dB; rest-frame leakage zero (RMS 0.001-0.004 vs sung peak ~0.39, ~40-60 dB suppression). | 30 天前 | |
docs(preprocess): document the RMVPE ONNX contract, add export script - README now states the real I/O: audio (batch, num_samples) in, salience (batch, time_frames, 360) out, 10 ms frames, 32-frame alignment, cents mapping and the 0.03 voicing threshold, plus the fixed mel params (n_fft 1024 / win 1024 / fmax 8000, not 2048 / 7600) - scripts/export_rmvpe_onnx.py reproduces the model end to end from the official rmvpe.pt, with --precision int8 (per-channel weight-only, same DequantizeLinear+Conv shape as the ModelScope build) and --verify that diffs the ONNX output against the torch reference | 1 天前 | |
feat(preprocess): make the F0 curve area collapsible Short reference clips leave the piano roll squeezed: the read-only F0 strip always eats 100px of the editor. Add a small "F0" toggle to the MIDI editor header — the same preprocessing window is used by the singer creator and by the new singer editor, so both get it. - constants.js owns the collapsed state (get/set + localStorage) because the layout is computed in three places (pianoRoll / canvasRenderer / uiControls); threading a parameter through all of them would be worse - every HEADER_HEIGHT + F0_CURVE_AREA_HEIGHT becomes HEADER_HEIGHT + getF0AreaHeight(); _drawF0Curve returns early at height 0 - toggling pins the pitch at the viewport centre: collapsing also shrinks maxScroll, so the clamp would otherwise shift notes downward and push them out of view (caught by the pixel check: note band went from y 127..333 to 227..419 before the fix) - the preference persists across windows/sessions, so editor and creator share one setting | 1 天前 | |
fix(singer): scroll the restored note range into view when editing The piano roll keeps scrollY = 0, so the viewport shows only the top ~20 semitones (G9 downward). A singer's notes usually sit around C4, which means a file opened for editing looked empty even though the notes had been restored (state.midiNotes was populated and the counter said "8 notes"). Add scrollPitchRangeIntoView(minPitch, maxPitch) and call it after restoring notes, centring the file's pitch range in the viewport. Also add the end-to-end harness that caught this: it loads the packaged audio_preprocess_window, injects an edit payload, then asserts the title, the restored note count, and that Save posts {filePath, notifyMainWindowUpdate} with all notes intact. | 1 天前 | |
chore(tools): ModelScope FP16 v2 上传脚本 + 忽略 .slidep 本地日志 - tools/upload_fp16_v2_to_modelscope.py:diff_step(rope 表烘焙)与 W16A32 vocoder 上传 release 分支,git push lightweight tag 打 v2 (SDK 1.37.1 create_model_tag 硬编码 Ref='master' 不可用); token 走环境变量/本地文件不入库,git 输出统一打码凭据。 - .gitignore 增加 .slidep/(本地工具日志目录)。 | 9 天前 | |
feat(intro-video): real-inference promo scenes + reproducible asset pipeline - intro-video: 新增 RealInferenceScene / SpecsScene,展示一次真实 SVS 推理 的输入(钢琴卷帘 + 中文唱词)与输出(梅尔频谱 / 波形 / 实测指标), 成片 30s @ 1920x1080/30fps,音频轨即真实推理输出 - scripts/intro-video-assets.js: 调用 OnnxSVSPipeline 在 CPU EP 上跑真实 推理(32 步扩散),产出 sample.wav 与 metrics.json,可复现 - scripts/intro-video-spectrogram.py: 从真实 WAV 计算梅尔频谱图 / 波形图 / RMS 包络,供宣传片动画使用 - forge.config.js: 修复 Linux deb/rpm 打包 —— electron-installer-debian 默认按 package.json 的 name(sxseditor) 找二进制,而 packager 产出的是 productName(SXSEditor),导致 make 直接失败;显式指定 bin 并补 maintainer/homepage。已在 Linux x64 实测产出 sxseditor_2.0.2_amd64.deb - .gitignore: intro-video 生成物交由子 .gitignore 管理,样例 WAV 加例外 | 2 天前 | |
feat: 应用 SXSEditor-full.patch(33 项审查修复 + 插件系统) 应用交付说明 SXSEditor-full.patch(基线 392cf62,94 文件,+8107/-502)。 主要内容: - 暂停按钮图标消失:新增 iconHelper.setLabel(),只写文本节点保留已注入的 SVG; 24 处 textContent 赋值改为 setLabel;applyLocale 改 appendChild。 - 审查报告 33 项(F-01…F-33)修复,含路径授权 realpath+8.3+denylist、 IPC 错误统一脱敏(新增 src/main/ipcSafe.js)、sandbox:true、模型清单、 i18n 补键、版本号统一为 app.getVersion() 等。 - 新增插件系统:pluginContract / pluginHost / pluginWorker / pluginIpc / pluginBackend / pluginTrackDialog / pluginBlockingOverlay / pluginEditorMode, 外加 plugins/example-concat 示例与 docs/dev/plugins.md。 本 commit 仅做原样应用;针对该 patch 的两处回归修复与瘦身改动见上一 commit。 | 18 天前 | |
fix(review): correctness, performance, readability and docs across 22 areas Full static review of the app (pipeline, renderer, editor, audio, main process, docs, tests), with every high-severity finding verified against the source before fixing. Correctness: - export mix buffer sized by fragment-local duration, silently dropping fragments that start later than the longest fragment - playhead animation dereferenced a null scheduler in sequential playback, freezing the playhead and time display - Basic Pitch passed a resolution constant as onsetThresh, disabling onset-based note splitting - WebNN NPU clamp reused the exact formula the pipeline documents as overflow-prone for prompts > 50 frames - piano-roll static cache was not invalidated after F0/MIDI extraction, so results stayed invisible until an unrelated redraw - audition preview called schedulePianoNote with misaligned arguments (TypeError, button dead) - Japanese multi-phoneme mora weights gave the last component the full weight instead of splitting it - Q-Drift was dropped on export and in chunked multi-stream synthesis - multi-stream synthesis bypassed the _synthPromise serialization - playback duration divided source length by the target sample rate - WAV envelope interpolation divided by zero on duplicate keyframes - SiFiGAN registry omitted its .onnx.data files - WebNN ran four encoders concurrently against ORT's shared WASM stack - autosave had no debounce and could write after "discard" - undo snapshots lost ArrayBuffer/Float32Array singer data - i18n keys missing (confirmDeleteSinger and others), several entries added to the wrong namespace - save-fragment IPC swallowed failures; 30s truncation was silent - MIDI extraction hardcoded 120 BPM; MIDI export hardcoded 4/4; Ctrl+D duplicated notes into overlapping positions - singer market used a 30s total timeout with a 512MB upload cap Performance: - pitch post-processing recomputed a full-segment median per frame (O(n^2 log n)); replaced with an incremental median (verified bit-identical on 800 randomized + 16 edge inputs) - separate-path diffusion allocated twice per step; now reuses scratch - Basic Pitch batched windows instead of one execute per window - notesIndex no longer re-verifies order on every read - kanji group lookup and phoneme hover use indices instead of scans - timeline grid cached offscreen; scroll metrics computed once - model tags / model-file checks cached with TTL and mtime signatures - streaming progress IPC throttled (100ms / 2%), matching the other paths - RMVPE argmax yields every 128 frames instead of blocking Readability: - removed dead code and stale comments (GPU drain timing, sampler JSDoc, unreachable branches, unused exports) - hardcoded UI strings moved to i18n - resampler naming clarified as windowed-sinc, not linear Docs: - test counts refreshed (86 files / 1840 cases / 1825 in CI) - 9 entry points + splash instead of "8 windows"; corrected entry paths - default locale is en, not zh-CN - path allow-list is three roots (home/temp deliberately removed) - sampler default is STORK-2; exclusive mode described as unimplemented - tools.md no longer references nonexistent scripts or hardcoded paths - Japanese status aligned with the shipped optional JP model pack Tests: - sinon sandbox in test/setup.js is now actually exported and restored - GPU-free modelLoader case split out of the CI-ignored file - assertions added to previously assertion-free cases - version tests reset the new tags cache between cases Test suite: 1946 passing, 31 pending, 7 failing. The 7 failures are Windows-only (NPU PnP probe, WinML onnxruntime.dll) and fail identically on the pre-change baseline in this Linux sandbox. | 3 天前 | |
feat: deploy FP16 diff_step for real 2.26x DML speedup, enable diffStep DML path Measured on real calib data (8 samples, seq 2048, DirectML): - FP16 full-graph: cos 0.99761 / SNR 27.31 dB / 181ms = 2.26x vs FP32 (410ms) - W8A32 (int8 weights + DQ): cos 0.99988 / SNR 38.1 dB but 0.94x (SLOWER) - DML has no mixed int8-weight x fp32-activation GEMM so DequantizeLinear cannot fuse into MatMul; kept as size-optimized fallback only - Absolute cross-check: fp16 DML vs CPU cos 0.99996; old silent-output issue gone Deployment: - onnx_models/int8/diff_step_dml.onnx replaced with FP16 compute / FP32 IO model (885 MB); pipeline detects float32 xt_input so FP32 feeding path unchanged - modelLoader.js: remove STATIC_SHAPE_DML_EXCLUDE, diffStep goes DML-first with CPU fallback in static-shape mode; NPU/WebNN paths untouched New scripts: make_fp16_diffstep.py (manual whole-graph FP16 conversion), bench_diffstep_realdata.py (unified accuracy+latency bench), _crosscheck_dml_cpu.py; build_w8a32_diffstep.py v2 fixes per-axis scale length bug (reduce all axes except quantization axis) and stores true int8 initializers | 1 个月前 | |
feat: 修改打包后模型下载逻辑 - 先检查app.asar.unpacked完整模型,缺少时询问用户下载位置 | 5 个月前 | |
feat: 应用 SXSEditor-full.patch(33 项审查修复 + 插件系统) 应用交付说明 SXSEditor-full.patch(基线 392cf62,94 文件,+8107/-502)。 主要内容: - 暂停按钮图标消失:新增 iconHelper.setLabel(),只写文本节点保留已注入的 SVG; 24 处 textContent 赋值改为 setLabel;applyLocale 改 appendChild。 - 审查报告 33 项(F-01…F-33)修复,含路径授权 realpath+8.3+denylist、 IPC 错误统一脱敏(新增 src/main/ipcSafe.js)、sandbox:true、模型清单、 i18n 补键、版本号统一为 app.getVersion() 等。 - 新增插件系统:pluginContract / pluginHost / pluginWorker / pluginIpc / pluginBackend / pluginTrackDialog / pluginBlockingOverlay / pluginEditorMode, 外加 plugins/example-concat 示例与 docs/dev/plugins.md。 本 commit 仅做原样应用;针对该 patch 的两处回归修复与瘦身改动见上一 commit。 | 18 天前 | |
feat: auto committed | 1 个月前 | |
feat(singer): edit an existing .sxssinger in the preprocessing window There was no way to change a singer after creation: the only paths were "create new" (creator → preprocessing → save) and "import into project". Fixing a wrong note or re-extracting F0 meant rebuilding the singer from the WAV and losing everything. Reuse the preprocessing window (it already owns pitch/note editing) in an "edit" mode instead of building a second editor: - main: openSingerFileForEdit() shows a picker, validates the file, decodes the embedded WAV and opens the preprocessing window with the existing midiNotes / f0Data / singerData plus the target path. Reachable from File → Edit Singer File… and from the singer picker dialog. - preprocessing window: restores notes and F0 after the piano roll is ready, titles itself "Editing singer · name · file", and Save writes straight back to the original .sxssinger (save-in-place, no Save As dialog). - main window: singerUpdated refreshes the singer that was loaded from that exact path (matched by singerFilePath) instead of adding a duplicate. - state is reset on every load so a reused window cannot write a new singer into the previous file. - parsing lives in src/shared/singerFileEdit.js (no electron dependency) so it is unit-testable; 11 cases cover JSON errors, missing fields, avatar MIME sniffing and payload shape. | 1 天前 | |
feat(intro-video): real-inference promo scenes + reproducible asset pipeline - intro-video: 新增 RealInferenceScene / SpecsScene,展示一次真实 SVS 推理 的输入(钢琴卷帘 + 中文唱词)与输出(梅尔频谱 / 波形 / 实测指标), 成片 30s @ 1920x1080/30fps,音频轨即真实推理输出 - scripts/intro-video-assets.js: 调用 OnnxSVSPipeline 在 CPU EP 上跑真实 推理(32 步扩散),产出 sample.wav 与 metrics.json,可复现 - scripts/intro-video-spectrogram.py: 从真实 WAV 计算梅尔频谱图 / 波形图 / RMS 包络,供宣传片动画使用 - forge.config.js: 修复 Linux deb/rpm 打包 —— electron-installer-debian 默认按 package.json 的 name(sxseditor) 找二进制,而 packager 产出的是 productName(SXSEditor),导致 make 直接失败;显式指定 bin 并补 maintainer/homepage。已在 Linux x64 实测产出 sxseditor_2.0.2_amd64.deb - .gitignore: intro-video 生成物交由子 .gitignore 管理,样例 WAV 加例外 | 2 天前 | |
ci: add release CI with Inno Setup packaging and rolling releases (issue release-ci-pipeline) | 3 个月前 | |
refactor(splash): 启动画面改用 BaseWindow + ImageView 位图,移除 HTML 渲染路径 启动画面此前是「内联 SVG + <text> 的静态 HTML」,首帧成本里仍含字体匹配与 字形 shaping(且仍要起一个渲染进程)。改为在主进程内直接绘制: - src/main/splashManager.js 重写为 new BaseWindow() + new ImageView(), nativeImage 两个 representation(2x/3x)挂同一个对象,各屏各取 1:1 位图; - scripts/generate-splash-image.js(新增,@napi-rs/canvas devDep)在构建期把 版面/亚克力卡片/版本号/构建时间烘进 PNG,src/splash@2x.png、@3x.png 为 构建产物(.gitignore),由 prestart / prepackage 生成; - scripts/generate-build-info.js 输出 buildDateDisplay / utcOffset / channel / buildYear 供位图直接拼接,不再做模板占位符替换;CI 在 release 分支导出 SXS_CHANNEL=stable,其余一律 Nightly; - webpack.main.config.js CopyPlugin 逐字拷两张 PNG 到 .webpack/main/, verify-build-assets.js 改为校验生成器(产物在其后才生成); - 删除 src/splash.html.template,src/preload.js 注释去掉 splash 窗口; - ImageView 属实验 API:类缺失或位图读不到时降级为「不显示启动画面」, 绝不阻断启动(test/splashAssets.test.js 守这条及窗口尺寸/倍率/CopyPlugin)。 窗口 480×272 transparent + hasShadow:false(圆角靠 per-pixel alpha), 尺寸必须等于生成器的 LOGICAL_W/H,否则 ImageView 会拉伸。 | 6 天前 | |
fix(singer): scroll the restored note range into view when editing The piano roll keeps scrollY = 0, so the viewport shows only the top ~20 semitones (G9 downward). A singer's notes usually sit around C4, which means a file opened for editing looked empty even though the notes had been restored (state.midiNotes was populated and the counter said "8 notes"). Add scrollPitchRangeIntoView(minPitch, maxPitch) and call it after restoring notes, centring the file's pitch range in the viewport. Also add the end-to-end harness that caught this: it loads the packaged audio_preprocess_window, injects an edit payload, then asserts the title, the restored note count, and that Save posts {filePath, notifyMainWindowUpdate} with all notes intact. | 1 天前 | |
chore: backup precision comparison scripts before FP16 re-quantization | 3 个月前 | |
feat: unify UI theme tokens, add NPU hardware detection and auto inference - theme: refactor tokenCatalog/themeBootstrap, align built-in themes and component styles on shared tokens, add ui-preview gallery and preview-server - npu: add src/main/npuHardware.js probe, rewrite WebNN NPU detection and webnnIpc device selection - inference: support auto inference after fragment edits (src/fragmentEditor/autoInference.js) - settings/i18n: add related settings entries and zh-CN/en copy - tests: add npuHardware cases, update themeTokens/crossModuleIntegration/streamingSynthesis - docs: add UI flatten proposal and SVS expression params research | 1 个月前 | |
fix(review): correctness, performance, readability and docs across 22 areas Full static review of the app (pipeline, renderer, editor, audio, main process, docs, tests), with every high-severity finding verified against the source before fixing. Correctness: - export mix buffer sized by fragment-local duration, silently dropping fragments that start later than the longest fragment - playhead animation dereferenced a null scheduler in sequential playback, freezing the playhead and time display - Basic Pitch passed a resolution constant as onsetThresh, disabling onset-based note splitting - WebNN NPU clamp reused the exact formula the pipeline documents as overflow-prone for prompts > 50 frames - piano-roll static cache was not invalidated after F0/MIDI extraction, so results stayed invisible until an unrelated redraw - audition preview called schedulePianoNote with misaligned arguments (TypeError, button dead) - Japanese multi-phoneme mora weights gave the last component the full weight instead of splitting it - Q-Drift was dropped on export and in chunked multi-stream synthesis - multi-stream synthesis bypassed the _synthPromise serialization - playback duration divided source length by the target sample rate - WAV envelope interpolation divided by zero on duplicate keyframes - SiFiGAN registry omitted its .onnx.data files - WebNN ran four encoders concurrently against ORT's shared WASM stack - autosave had no debounce and could write after "discard" - undo snapshots lost ArrayBuffer/Float32Array singer data - i18n keys missing (confirmDeleteSinger and others), several entries added to the wrong namespace - save-fragment IPC swallowed failures; 30s truncation was silent - MIDI extraction hardcoded 120 BPM; MIDI export hardcoded 4/4; Ctrl+D duplicated notes into overlapping positions - singer market used a 30s total timeout with a 512MB upload cap Performance: - pitch post-processing recomputed a full-segment median per frame (O(n^2 log n)); replaced with an incremental median (verified bit-identical on 800 randomized + 16 edge inputs) - separate-path diffusion allocated twice per step; now reuses scratch - Basic Pitch batched windows instead of one execute per window - notesIndex no longer re-verifies order on every read - kanji group lookup and phoneme hover use indices instead of scans - timeline grid cached offscreen; scroll metrics computed once - model tags / model-file checks cached with TTL and mtime signatures - streaming progress IPC throttled (100ms / 2%), matching the other paths - RMVPE argmax yields every 128 frames instead of blocking Readability: - removed dead code and stale comments (GPU drain timing, sampler JSDoc, unreachable branches, unused exports) - hardcoded UI strings moved to i18n - resampler naming clarified as windowed-sinc, not linear Docs: - test counts refreshed (86 files / 1840 cases / 1825 in CI) - 9 entry points + splash instead of "8 windows"; corrected entry paths - default locale is en, not zh-CN - path allow-list is three roots (home/temp deliberately removed) - sampler default is STORK-2; exclusive mode described as unimplemented - tools.md no longer references nonexistent scripts or hardcoded paths - Japanese status aligned with the shipped optional JP model pack Tests: - sinon sandbox in test/setup.js is now actually exported and restored - GPU-free modelLoader case split out of the CI-ignored file - assertions added to previously assertion-free cases - version tests reset the new tags cache between cases Test suite: 1946 passing, 31 pending, 7 failing. The 7 failures are Windows-only (NPU PnP probe, WinML onnxruntime.dll) and fail identically on the pre-change baseline in this Linux sandbox. | 3 天前 | |
feat: unify UI theme tokens, add NPU hardware detection and auto inference - theme: refactor tokenCatalog/themeBootstrap, align built-in themes and component styles on shared tokens, add ui-preview gallery and preview-server - npu: add src/main/npuHardware.js probe, rewrite WebNN NPU detection and webnnIpc device selection - inference: support auto inference after fragment edits (src/fragmentEditor/autoInference.js) - settings/i18n: add related settings entries and zh-CN/en copy - tests: add npuHardware cases, update themeTokens/crossModuleIntegration/streamingSynthesis - docs: add UI flatten proposal and SVS expression params research | 1 个月前 | |
refactor(splash): 启动画面改用 BaseWindow + ImageView 位图,移除 HTML 渲染路径 启动画面此前是「内联 SVG + <text> 的静态 HTML」,首帧成本里仍含字体匹配与 字形 shaping(且仍要起一个渲染进程)。改为在主进程内直接绘制: - src/main/splashManager.js 重写为 new BaseWindow() + new ImageView(), nativeImage 两个 representation(2x/3x)挂同一个对象,各屏各取 1:1 位图; - scripts/generate-splash-image.js(新增,@napi-rs/canvas devDep)在构建期把 版面/亚克力卡片/版本号/构建时间烘进 PNG,src/splash@2x.png、@3x.png 为 构建产物(.gitignore),由 prestart / prepackage 生成; - scripts/generate-build-info.js 输出 buildDateDisplay / utcOffset / channel / buildYear 供位图直接拼接,不再做模板占位符替换;CI 在 release 分支导出 SXS_CHANNEL=stable,其余一律 Nightly; - webpack.main.config.js CopyPlugin 逐字拷两张 PNG 到 .webpack/main/, verify-build-assets.js 改为校验生成器(产物在其后才生成); - 删除 src/splash.html.template,src/preload.js 注释去掉 splash 窗口; - ImageView 属实验 API:类缺失或位图读不到时降级为「不显示启动画面」, 绝不阻断启动(test/splashAssets.test.js 守这条及窗口尺寸/倍率/CopyPlugin)。 窗口 480×272 transparent + hasShadow:false(圆角靠 per-pixel alpha), 尺寸必须等于生成器的 LOGICAL_W/H,否则 ImageView 会拉伸。 | 6 天前 | |
refactor(splash): 启动画面零 JS 化,移除 preload/bundle 与 IPC 往返 splash 改为由 src/splash.html.template 在构建期生成 src/splash.html,整个载荷是一段内联 SVG,版本号/日期/图标在构建期写死,首帧零 JS(preload 编译+执行实测约 100ms 渲染进程启动开销被整段去掉): - 删除 src/splash.js、src/splashPreload.js;splashManager 改用 loadFile() 直接加载 .webpack/main/splash.html(webpack.main CopyPlugin 逐字拷贝),不再注册 SPLASH_GET_BUILD_INFO IPC。 - 从 forge/wrenderer 入口移除 splash_window(electron-forge 强制要求 entryPoint 带 js,而 splash 恰恰要零 JS,进 webpack 入口会触发 schema 校验失败、整个 dev server 起不来)。 - generate-build-info.js 增加模板占位符替换(含未替换占位符自检);verify-build-assets 增加 REQUIRED_SPLASH_ASSETS(模板)守卫,防止 CopyPlugin noErrorOnMissing 静默跳过导致打包成功但启动画面 404。 - 同步 .gitignore(splash.html 改为生成产物不再提交)、eslint、ipcChannels、main.js、docs 架构图。 | 6 天前 | |
Initial commit: SXSEditor AI歌声合成工作台 + 官方网站 (#1) | 5 个月前 |
中文
SXSEditor 是一款开源的歌声合成桌面应用。它基于 ONNX Runtime 运行 SoulX-Singer 神经模型,支持 DirectML GPU、WebNN NPU/GPU 以及 CPU 推理。在 Windows 11 24H2 及以上系统中,可通过实验性的 Windows ML 加速 选项(设置 → ORT 高级)利用插件执行提供程序进一步加速主模型(diff_step / vocoder / preflow)—— NVIDIA RTX → TensorRT-RTX,Intel/AMD → OpenVINO/MIGraphX,Snapdragon NPU → QNN —— 并支持自动回退至 DirectML/CPU。
支持的歌声语言:英语、中文(普通话) 和 日语。
平台支持:Windows 为主要平台(提供安装包 + DirectML/WebNN 加速)。macOS/Linux 仅限源码编译——仅支持 CPU 推理,无 DirectML/Windows ML 加速,且不在 CI 覆盖范围内,也不提供预编译发布包。请参阅开发者文档。
许可证
中文
SXSEditor 是一个开源的桌面歌声合成应用。基于 SoulX-Singer 神经网络模型,通过 ONNX Runtime 运行,支持 DirectML GPU、WebNN NPU/GPU 和 CPU 推理。在 Windows 11 24H2+ 上,可在设置中开启实验性的 Windows ML 加速,通过插件执行提供者加速主模型(diff_step / vocoder / preflow):NVIDIA RTX → TensorRT-RTX,Intel/AMD → OpenVINO/MIGraphX,高通 NPU → QNN;失败自动回落 DirectML/CPU。
支持的合成语言:中文(普通话)、英语 和 日语。
平台支持:Windows 是主要平台(提供安装包与 DirectML/WebNN 加速)。macOS/Linux 需从源码构建,仅支持 CPU 推理,不含 DirectML/Windows ML 加速,且无 CI 覆盖、无官方二进制。详见开发者文档。
许可证
日本語
SXSEditor 是一款开源的桌面歌声合成应用。基于 SoulX-Singer 神经网络模型,通过 ONNX Runtime 运行,支持 DirectML GPU、WebNN NPU/GPU 和 CPU 推理。
支持的合成语言:中文(普通话)、英语 和 日语。
平台支持:Windows 是主要平台(提供安装包与 DirectML/WebNN 加速)。macOS/Linux 需从源码构建,仅支持 CPU 推理,不含 DirectML/Windows ML 加速。无 CI 验证,也无官方二进制文件。 详见开发者文档。