尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗網址:https://nilson0606.github.io/sign_record/
桌機 Windows + Chrome/Edge 優先。GitHub Pages 提供介面;YouTube 音訊取得、格式驗證、人聲分離、旋律/節拍估計,以及麥克風評分都在自己的電腦執行。本專案僅提供桌機版。
預設繁體中文;頁首「語言 / Language」可切換 English,並在此瀏覽器記住選擇。切換不重載頁面、不停止試聽,也不改動歌曲、錄音、音量或延時設定。說明連結會開啟相同語言的操作手冊。
The interface defaults to Traditional Chinese. Choose English in the header; the choice is remembered in this browser. Switching language preserves playback and settings. See the English user guide.
i18n-catalog.mjs. Exact Chinese messages are keys; dynamic templates use numbered placeholders. The third array lists UI-fragment slots that may be translated recursively; the optional fourth lists generated segment-name slots. Leave user titles, model names, and paths out of those lists.i18n.mjs translates text and accessibility attributes in place and retains their Chinese source for switching back. Unknown diagnostic messages remain verbatim. It does not translate stored metadata, input values, or filenames, and makes no translation service requests.data-i18n-user, or use userText / userOption. Use originalText when composing another message from translated DOM text, and localizedConfirm for confirmation dialogs. Do not use displayed text as application state.npm test, node build-site.mjs, and node tests/i18n-browser-check.mjs (Playwright and desktop Edge required). The browser check uses isolated fixtures and verifies language coverage, preserved values and playback, persistence, dialogs, and both manuals.本專案從 0925 評分版還原點建立;第一版 UI 已依討論收合設定、遮罩與試聽。GitHub Pages 只發布 build-site.mjs 明確列出的網頁資產,歌曲、分離音軌、錄音、模型、Python 執行環境與本機路徑設定不會上傳。
127.0.0.1:4274,與原專案的 4174 分開。start-local.ps1 啟動此目錄的工具與開發頁面,預設開啟本機頁面;也可自行使用上方 Pages 網站。stop-local.ps1 只停止本專案的行程:除了 .runtime/*.pid 記錄的,也會找出佔用 4273/4274、或命令列是本資料夾 server.mjs/helper-local.mjs 的 node.exe(例如不是由 start-local 啟動的舊小幫手),以及上層已結束、仍在跑 .runtime\、tools\ 檔案的殘留工作。小幫手會先透過自己的 /shutdown 取消工作,仍未結束才用 taskkill /T;最後確認兩個埠都已釋放,否則顯示警告並以結束碼 1 結束。加 -List 只列出會停止哪些行程、不停止。其他 Node 程式(含其他專案的 server.mjs)不會被動到。GET /busy(只檢查 Origin、不需 token),回報準備歌曲、MV、本機影音、本機收音、歌曲庫變更是否進行中,供 AI_COVER_MV 入口頁在「全部關閉」前提醒。powershell -NoProfile -ExecutionPolicy Bypass -File .\setup-local.ps1。只需初次安裝;模型第一次分離時才下載。powershell -NoProfile -ExecutionPolicy Bypass -File .\start-local.ps1,工具會在背景啟動並開啟網站。若網站詢問麥克風/本機網路權限,請允許。.runtime/library-settings.json;不寫死開發者路徑。初次升級若找到舊 .runtime/library 會建議使用,確認後即可沿用。切換歌曲庫不搬動或刪除舊資料;歌曲載入期間需先取消/卸載再切換。基準自動保存在指定資料夾;同一影片及分析範圍下次直接載入,不用再分離。展開「本機歌單」點歌曲名稱即可載入,並自動卸載前一首的暫存工作(不刪除已保存歌曲);點目前歌曲不會重複載入。每筆顯示容量,也可刪除;15/30/60 秒與完整歌曲分開保存。結束本機工具:powershell -NoProfile -ExecutionPolicy Bypass -File .\stop-local.ps1(先看會停止什麼:加 -List)。啟停腳本的模擬測試(任何有 PowerShell 7 的系統):pwsh -NoProfile -File tests/stop-local-check.ps1、pwsh -NoProfile -File tests/start-local-check.ps1。
重開機不會移除安裝,但需要重新啟動工具。Windows 重設/重灌或搬到新電腦後應重建 Python 虛擬環境,即使原工具資料夾仍在。若沒有 Python Launcher,可用 setup-local.ps1 -PythonPath 'C:\path\to\python.exe' 指定 Python 3.12。
錄音診斷開啟時,開始前會先確認錄音本機工具(4274)可建立診斷檔;無法連線或寫入時不開始錄音。停止後會等待診斷寫完,核對診斷取樣數與錄音相同,再保存完成狀態。中途診斷失敗仍保留演唱錄音,錯誤原因會一併存入錄音資料並顯示,不會只留診斷編號而報成功。診斷沿用專案 .runtime/recording-diagnostics,不依賴本機網頁服務;升級後需重新啟動本機工具並重新整理網頁。此修正不會補回舊錄音當時未保存的對照訊號。
診斷驗證:node --test tests/recording-diagnostics.test.mjs 與 node tests/recording-diagnostics-browser-check.mjs,使用隔離資料及合成音訊,涵蓋寫入失敗、暫停續錄、WAV 與診斷 PCM 逐取樣一致、完成前等待保存及失敗狀態保留。
播放器下方的「開啟分段模式」提供獨立的分段錄製流程;「從頭開始唱」及原整首評分保留。分段練唱、跳段與錄音不會寫入整首分數,若已有未結算演唱,需先結算。
mm:ss.sss、提前/延後 0.1 或 1 秒,並可復原或移除。相鄰段落共享同一分界。驗證:node tests/recording-live-preview-browser-check.mjs 檢查即時兩路增益、不中斷播放、跳轉與原唱區間;node --test tests/recording-segments.test.mjs;node tests/recording-segments-browser-check.mjs 使用隔離歌曲、模擬播放器與實際 Web Audio PCM,不存取使用者真實錄音。
「聲曲分離模式」預設仍是人聲/伴奏。選「主唱/和音分離」時,先用所選的 Demucs、BS-RoFormer 或 Mel-Band RoFormer 取得全部人聲,再用 audio-separator 的 Mel Band Roformer Karaoke 模型 mel_band_roformer_karaoke_aufr33_viperx_sdr_10.1956.ckpt 估計主唱與和音;旋律基準只從主唱擷取。伴奏節拍分析維持原方式。這不是歌手身分辨識,齊唱、二重唱、疊軌仍可能分錯,請用試聽判斷是否適合該歌。
第一次需額外下載約 913 MB 模型,保存於 .runtime/models/lead;之後重用。現有安裝先停止工具、更新程式碼、重跑 setup-local.ps1 再啟動,會安裝配對 TorchVision 0.20.1、audio-separator 0.47.0 與相關依賴。此模型的推論使用 PyTorch CUDA(可用時);CPU ONNX Runtime 是套件匯入所需,不代表 Roformer 只能用 CPU。GPU 錯誤會用獨立 CPU 程序重試。
勾選保留音軌時,主唱模式保存人聲、伴奏、主唱、和音四條本機 MP3。一般與主唱模式使用不同歌曲庫 ID,互不覆蓋;舊歌曲視為一般人聲模式。重新分離僅覆蓋所選模式,缺少任一必要音軌時不發布新結果。變更模式後需按「準備歌曲基準」或「重新分離並覆蓋」才生效。
HTML 操作手冊 可從主畫面上方的「操作手冊 ↗」開新分頁,涵蓋安裝、歌曲庫、分離試聽、評分範圍、再唱與常見問題。
安裝腳本預設偵測 NVIDIA 顯示卡,安裝配對的 PyTorch/TorchAudio 2.5.1 CUDA 12.4 版(約 2.5 GB);未偵測到則使用 CPU 版。既有 CPU 安裝可先停止本機工具,重新執行 setup-local.ps1 再啟動;模型與歌曲庫不會移除。可用 setup-local.ps1 -Device cpu 指定 CPU 套件,或 -Device cuda 指定 CUDA 套件。
每次新分離會檢查 CUDA 是否可用;可用時優先使用 GPU。GPU 記憶體不足或 CUDA 執行失敗時,自動以新的 CPU 程序重試一次,進度歸零並顯示原因;一般檔案或下載錯誤不會誤當 GPU 故障。進度區顯示實際 GPU/CPU;已保存歌曲仍直接載入快取,不重新分析。需要強制 CPU 診斷時可執行 audio_pipeline.py --input <檔案> --separate --device cpu。加速幅度取決於硬體與歌曲長度,不影響評分權重。
在 RTX 4060 Laptop GPU(8 GB)上,以相同 30 秒合成音訊驗證:GPU 約 6.2 秒、CPU 約 17.7 秒,包含本機檔案驗證、分離及兩軌完整解碼驗證;不含下載與旋律分析。此短片段測試約快 2.9 倍,不代表每首歌的固定加速比。自動測試另涵蓋無 CUDA、GPU 記憶體不足後 CPU 重試,以及重試進度歸零。
tools/native_capture.py 直接讀取 WASAPI 封包,SoundCard 0.4.6 只負責開關裝置;不再使用其 record() 的等待逾時/空封包補零邏輯。裝置緩衝容量保留 500 ms(24,000 個 48 kHz 音框),仍每 20 ms 讀取/傳送,不等待容量填滿;增加容量是為降低短暫卡頓時溢位的機率,不代表偶發中斷已根治。人聲/伴樂校正預設為 300 ms。取音執行緒註冊 Windows MMCSS Audio 優先排程;管線寫入與監聽改由另一執行緒按順序送出,避免輸出阻塞連帶拖住裝置取音。傳送佇列最多容納 2 秒,正常即到即送;超出才明確回報,不丟棄樣本或補假靜音。等待後先重查資料;連續收音超過 100 ms 無資料、資料損壞或無法確認時間戳時停止,保留有效資料。wasapi-packets-v2 撤回 v1「收到不連續旗標就停錄」的行為:只要封包仍有合法 PCM,就保留全部實際樣本並繼續,將旗標記為警告;不因旗標補零、複製或丟棄樣本。這是修正過度停錄,並不保證底層音訊沒有缺口,也不代表原先的斷音已根治。警告/錯誤包含最近 12 個封包的音框數、裝置位置、QPC 時間戳與讀取間隔,供量化實際缺口,不包含音訊內容。裝置位置不直接與 48 kHz 輸出封包長度相加比較:USB 麥克風在共用模式重取樣時,兩者可使用不同單位,不能據此判定掉音;位置差異只記一次診斷。只有 Windows 明確標示 SILENT 的封包才按其實際長度轉成靜音。啟動、晚到、裝置靜音及錯誤記在 .runtime/native-capture.jsonl(約 1 MiB 輪替,保留前一份,不含聲音);新錄音 metadata 的 captureClock.nativeCapturePolicy/nativeCaptureId 可對照診斷。更新後須重啟本機工具並重新開啟麥克風,收音方式仍選「本機相容收音」。無硬體回歸測試:python -m unittest discover -s tests -p test_native_capture.py。實機長時間測試:python tests/native-capture-long-check.py --device JAZZ --seconds 120(裝置名稱可替換;只統計 PCM 長度與診斷,不保存聲音)。完整實機瀏覽器管線測試:node tests/native-capture-live-browser-check.mjs(需啟動本機工具、4273 埠閒置;預設 Realtek、240 秒,可用 CAPTURE_DEVICE/CAPTURE_SECONDS 覆寫;同時跑雙軌 Key 播放、音高分析與 PCM 錄音,音訊只在記憶體內處理)。這是練習評分,尚未經過真人演唱資料集與人工標註驗證,不能宣稱專業準確度。不辨識歌詞,也不能判定情感、音色或唱法好壞。伴奏外放進入麥克風可能造成誤判,建議戴耳機。
展開「Do Re Mi Fa Sol 五音延遲測試」,開啟麥克風後選 C4–G4 或 C3–G3 音域,按「播放五音並測試」。每音相隔 1.2 秒,音長約 0.6 秒。
.runtime/venv 是安裝的工具,.runtime/models 是可重用的模型。.runtime/jobs/<id> 暫存下載及分離音檔;建立數值基準後立即刪除音訊,數值基準保存到所選歌曲庫的 <影片_範圍_版本>/reference.json;勾選試聽時同時保存 128 kbps MP3 人聲與伴奏。原始混音、大型 WAV 及磁碟工作目錄會刪除。{title, score},不保存音訊、基準、時間戳或影片 ID。本機服務只綁定 127.0.0.1:4274,檢查 Host 與 Origin,工作 API 需要頁面向本機取得的記憶體權杖。允許來源為本站 GitHub Pages origin 與本機開發頁面。GitHub Pages 同帳號的網站共享 origin,請將該帳號下網站視為同一信任範圍。
22 項 JavaScript 單元測試、15 項 Python 測試通過;Edge/Chrome 已驗證一般/主唱模式切換、四條音軌的瀏覽器解碼播放、重做、卸載,以及手冊新分頁與手機寬度排版。模擬管線確認一般模式使用全部人聲、主唱模式使用主唱建立基準,並清除未選擇保留的暫存產物。
另以 8 秒合成音訊實際執行新模型,主唱及和音輸出均為 8 秒、44.1 kHz 雙聲道,完整解碼通過。此為短片段功能測試,沒有驗證整首歌的長時間負載或真人歌曲分離品質。
npm start
npm test
.runtime\venv\Scripts\python.exe -m unittest discover -s tools -p "test_*.py"
node tests/browser-check.mjs
node tests/flow-check.mjs
node tests/calibration-browser-check.mjs
# 需先啟動 helper;會連網取得 30 秒測試歌曲,保存 30 秒歌曲及試聽檔,供後續瀏覽器測試:
node tests/local-pipeline-check.mjs
node tests/library-browser-check.mjs
開發頁面為 http://localhost:4273。瀏覽器測試需要 Playwright;PLAYWRIGHT_PACKAGE_ROOT 可指定含 Playwright 依賴的 package.json。BROWSER_CHANNEL=chrome 可切換流程測試至 Chrome,預設 Edge。測試使用合成音訊,不開啟實體麥克風。流程測試模擬播放器與本機回應;網路管線測試另行驗證真實下載及 Demucs。手機寬度檢查不代表 iPhone Safari 真機通過。
已驗證:14 項 JavaScript 單元測試(頻率、噪音、網址、分數、八度差、唱晚、歌曲庫及五音量測);5 項 Python 測試(網址、旋律及已知節拍)。Edge 流程測試的合成低八度聲音在允許模式 98 分、嚴格模式 15 分,含暫停、緩衝、取消和紀錄欄位驗證。Chrome 同流程也通過,允許模式 100 分、嚴格模式 15 分。數值可能因瀏覽器採樣時序略變。
真實本機管線測試:Twinkle Twinkle Little Star(Super Simple Songs)前 30 秒,在這台電腦約 21 秒完成下載、驗證、CPU Demucs 分離及參考分析。長度 29.994 秒,估計有音高的區間 10.1 秒、88.2 BPM;生成後暫存工作目錄已清除;新版另將基準與選用試聽存入歌曲庫,實測快取命中可直接載入。這證明流程可通,不代表擷取的每個音符均正確。五音瀏覽器測試透過合成 Web Audio 回收路徑插入已知 200 ms 延遲,辨識 5/5 音、建議 +200 ms;這不等同真人或藍牙硬體實測。
推送 main 後,GitHub Actions 執行單元測試,使用 node build-site.mjs 將 CSS 與所有前端模組放入依內容產生的 assets/<版本>/ 目錄;HTML 及模組相對匯入都指向同一版本,避免舊快取忽略新選項。只發布 index.html、manual.html、navigation.mjs、style.css、app.mjs、audio.mjs、session.mjs、scoring.mjs、calibration.mjs。本機工具、測試檔案與 .runtime 不進 Pages。網頁程式更新後可能需 Ctrl+F5;本機工具更新後需重新啟動。
run-local-audio.ps1 是開發診斷指令,會留下輸出供檢查,不是一般網頁流程;使用後自行清除該工作目錄。原始 --input 檔案不會被刪除。
使用限制:本機測試用途,不得商用。請尊重著作權,只處理有權使用或已取得授權的內容;本工具不提供歌曲內容或使用授權。自動分析與評分僅供測試參考,不保證準確性。
資料夾選擇會開啟可見的 Windows 選擇視窗;網頁上的「取消資料夾選擇」只取消這個視窗,不需要卸載歌曲,也不刪除已保存的歌曲庫。等待超過一分鐘會自動解除,之後可重試或直接輸入路徑。
歌曲準備顯示取得音訊、聲曲分離、建立基準、完成等階段(主唱模式另含主唱/和音分離)。分離百分比來自 Demucs 或 RoFormer 實際完成的推論片段;沒有可靠百分比的階段顯示不定進度,並非依時間假造百分比。資料夾選擇使用 Windows 檔案總管式視窗,只將使用者選定的路徑回傳網頁。
「聲曲分離模型」提供 Demucs/htdemucs(預設)與 BS-RoFormer/Viperx 1297。後者固定使用 model_bs_roformer_ep_317_sdr_12.9755.ckpt,約 639 MB,首次自動下載至 .runtime/models/bs-roformer。另可選 Mel-Band RoFormer/Kim 人聲,使用 Kimberley Jensen 的原始 MelBandRoformer checkpoint(約 913 MB),固定作者版本 ac9b0614ab3cd7f77219e18ba494dfd93956c348,以 audio-separator 目錄名稱 vocals_mel_band_roformer.ckpt 保存於 .runtime/models/mel-roformer;這與主唱/和音專用 Karaoke 模型不同。三者皆可搭配主唱/和音分離;RoFormer 共用既有 audio-separator 依賴,batch 1、segment 256、overlap 4。模型下載先寫暫存檔,完整收到才發布,斷線重試且失敗不留下可被誤認為完整的模型。
既有歌曲沿用原目錄,不做遷移;沒有 separationModel 的舊資料視為 demucs。BS-RoFormer 的快取 ID 多 _bs-roformer,Mel-Band RoFormer 多 _mel-roformer,同影片、範圍與人聲模式可並存。覆蓋及刪除只影響對應版本;歌單、就緒及試聽訊息標示模型。補建試聽保持目前載入的模型。新版頁面遇到不支援模型選擇的舊本機工具會明確要求更新,不會默默使用 Demucs。
本次驗證:26 項 JavaScript、18 項 Python 測試;Edge/Chrome 的正式版資產通過模型切換、舊庫載入、試聽、主唱模式、覆蓋、舊工具攔截與手冊檢查。另以 8 秒合成音訊實際執行 BS-RoFormer,兩條 WAV 都輸出 8 秒、44.1 kHz 雙聲道並完整解碼。短測只確認功能,不代表真人歌曲分離品質或長時間負載驗證。
audio-separator 0.47 的 soundfile writer 會沿用輸入 subtype,MP3 的 MPEG_LAYER_III 在輸出 WAV 時造成 Supported file format but unsupported encoding,發生於推論完成之後。tools/roformer_audio.py 現在先將壓縮來源解碼為浮點 WAV,合法 PCM/float WAV 則直接使用;暫存解碼檔在成功或失敗後均清理。沒有更換模型或改寫既有歌曲庫。
回歸測試使用真正 MP3、FFmpeg、soundfile 與套件原本的 WAV writer,確認兩條輸出可保存;另以 8 秒 MP3 實際執行 BS-RoFormer,兩條浮點 WAV 及試聽 MP3 完整解碼通過。先前僅用 WAV 的短測無法覆蓋這個錯誤。helper 現在也記錄工作 ID、快取版本、處理階段與失敗摘要到本機 stdout 日誌,避免前端清除工作後失去錯誤線索;不記錄音訊或認證權杖。
播放器下方可輸入秒數/分:秒,或以播放器位置標記起訖後新增,多段可刪除/全部清除,預設為空。保存至歌曲庫 .masks/<videoId>_<rangeSeconds>.json 的 masks: [{start,end}];同一影片及分析範圍跨分離模型、模式、音高方式共用。只在最終評分/顯示時套用,不修改旋律原始 frames 或試聽音檔。舊庫尚無共用檔時讀取最近保存且非空的舊 reference 遮罩;修改後寫入共用檔(空清單也會覆蓋舊遮罩)。換模型/重新分離不需重標,刪除單一模型不刪共用遮罩。
遮罩以相交時間格排除音準、進拍與完整度,起點包含、終點不包含;不允許跨遮罩配對起音。藍色基準線中斷、右側原唱音符顯示休息;影片不跳過或靜音。每輪建立獨立快照,期間禁止編輯;全遮罩或僅休息的演唱不產生分數。保存成功才在頁面套用。
本機工具增加 score-masks capability 與已驗證來源/session token 保護的 POST /library/:id/masks。原子替換 JSON,最多 100 段,排序合併重疊或相接區間;同筆分離/保存進行中回覆 409。更新後需重新啟動本機工具,既有庫不需重新分離。操作步驟見 HTML 手冊「選用:不計分遮罩」。
遮罩驗證:32 項 JavaScript 測試通過,涵蓋全遮罩不產生分數、區間端點、三種難度/兩種範圍、起音不能跨遮罩匹配、原子保存及工具重啟後載入。Edge/Chrome 正式版資產通過多段新增、位置標記、保存失敗、載入/模型隔離、休息顯示、演唱中鎖定、刪除/清除及桌機/窄螢幕版面檢查。
pitchMethod 為 yin(舊版及預設)或 rmvpe,API 與前端都驗證;pitch-methods capability 防止舊工具靜默回傳 YIN。快取 ID 只對新方法增加 _rmvpe,歌單/就緒訊息標示方法。分離模型與人聲模式仍獨立選擇;遮罩則依上述原始時間軸共用。
已有同影片/範圍/分離模型/模式的另一種音高版本,且保留音軌時,reference_worker.py 直接從保存的 MP3 建立新基準及複製試聽,不重新下載或分離。不保留音軌的舊歌需完整處理;明確按「重新分離並覆蓋」仍會重新分離。新版本失敗不覆蓋舊版本。新舊基準的輸入可能分別為保存 MP3 和原始分離 WAV,這是重用方案的取捨。
RMVPE 權重為 181,184,272 bytes(約 181 MB / 172.8 MiB),共用路徑 .runtime/models/rmvpe/rmvpe.pt。下載驗證固定 SHA-256,權重以 weights_only=True 讀取;來源與 Apache-2.0 程式碼授權見 tools/vendor/rmvpe/NOTICE.md。使用既有 torch/librosa,不需另裝整套聲音轉換工具。推論每段核心 8 秒、前後各 1 秒上下文,保留原始時間,將 10 ms 預測以多數有效及中位数映射到 100 ms 格線;限制 65–1000 Hz,不把不確定音高強制補滿。優先 GPU,相關 GPU 錯誤才重試 CPU,失敗不默默改成 YIN。試聽音軌與麥克風即時 YIN 不變。
RMVPE 驗證:33 項 JavaScript、24 項 Python 測試;Edge/Chrome 的正式版資產通過新選項、舊工具攔截、歌單方法辨識與跨模型共用遮罩。實際以 3 秒合成訊號跑 CPU,及從已存《吻別》音軌取 8 秒跑推論/本機 HTTP 工作完整流程,確認重用音軌、80 格基準、保存、遮罩繼承、原試聽 bytes 不變及第二次直接載入快取;沒有重新下載歌曲或重新分離。短測確認流程,沒有宣稱整首歌音高更準或長時間負載已驗證。
試聽依已載入 reference.cacheId 取得音檔;Demucs/BS/Mel 使用不同 ID。試聽區固定顯示實際歌曲、模型與模式。改選尚未套用的分離模型/人聲模式會停止並清除舊 blob,停用試聽直到準備完成;只切換音高方式不改音軌。前端取檔也明確 cache: no-store(本機 API 原有 Cache-Control: no-store)。Edge/Chrome 回歸測試使用不同音訊 bytes 模擬三種模型,逐一核對實際請求 ID 和 audio 元件 blob 雜湊,包含切回 Demucs。
另在本機實際比對《老鼠愛大米》Demucs/BS 的試聽 API bytes 與歌曲庫檔案一致、雜湊不同;取第 45、90、180 秒各 8 秒解碼後,三段 PCM 都不同,排除只差檔案標頭。此檢查證明音軌有切換,不代表 BS 分離品質一定更好。
「歌曲基準處理流程」預設 single,保持原有分離管線;residual 使用所選 Demucs、BS-RoFormer 或 Mel-Band RoFormer 連續處理原曲和第一輪伴奏,再計算 V = M - I2。不是把第一輪伴奏直接相減,也不是將人聲再淨化。可與主唱/和音、YIN/RMVPE 組合;主唱分離放在相減後。
新流程先將來源轉為 44.1 kHz 雙聲道浮點 WAV,兩輪輸出禁用獨立音量正規化/削波。Demucs 由 tools/demucs_lossless.py 在子程序內改用 float writer;BS worker 的 --preserve-gain 關閉輸入及輸出峰值縮放,不修改已安裝的套件。tools/residual_separation.py 驗證相同樣本長度、聲道與取樣率,以區塊相減並拒絕非有限數值。未對齊不默默截切或補零。
歌曲 metadata 新增 separationMethod;舊資料缺欄位視為 single。新 cache ID 在 _v1 前加 _residual,模型、模式與音高方式各自區隔。跨 YIN/RMVPE 重用音軌限於同一流程;遮罩仍以影片和分析範圍共用。API capability 為 residual-separation,舊 helper 必須更新重啟,前端會明確提示。
進度新增第二輪伴奏與反向相減,第二輪從 0% 開始;相減沒有假造進度。整體等待上限新流程為 60 分鐘,單次仍為 30 分鐘,單個模型子程序仍有原本逾時限制。兩種流程在歌單與試聽來源均有標示;改選但未載入時停用舊試聽。新流程不保證較乾淨,需以實際歌曲比較。
本次驗證:35 項 JavaScript、30 項 Python 測試通過;Edge/Chrome 驗證單次/二次流程切換、實際載入的試聽 bytes、第二輪進度、舊 helper 攔截、遮罩與 YIN/RMVPE 組合。另以 2 秒合成雙聲道音訊在 CPU 實際跑完 Demucs 與 BS-RoFormer 各兩輪,88200 個樣本保持對齊,V + I2 與混音最大誤差低於 2e-7。這些只驗證流程和波形運算,不代表整首長時間負載或真人歌曲分離品質驗證。短測另外發現 Windows 的空 CUDA 裝置遮罩會產生 available=true、count=0;BS worker 已選定 CPU 時改用明確的 -1 遮罩,預設 GPU 選擇不變。
預設仍為 Demucs,新增 Mel-Band RoFormer/Kim 人聲,可搭配單次或伴奏二次分離+反向相減。固定同一影片與分析範圍時,3 模型 × 2 流程 × 2 人聲模式 × 2 音高方式,共 24 種結果可各自保留,全部共用同一份遮罩。新模型有獨立 mel-roformer helper capability,舊工具會要求更新,不會誤用原模型。手冊含切換與試聽步驟。
模型下載器修正 GitHub 壓縮回應的長度判定:串流已解壓縮時,不拿壓縮 Content-Length 與解壓後的位元組數比較;仍拒絕空檔,未壓縮的截斷回應和串流中斷仍會重試,完成前不發布模型檔。
驗證:36 項 JavaScript、32 項 Python 測試通過;24 組合的遮罩共用、快取隔離、覆蓋後保留遮罩均有回歸測試。以原作者 SHA-256 87201f4d31afb5bc79993230fc49446918425574db48c01c405e44f365c7559e 核對下載的 Mel checkpoint,並在 CPU 實跑 2 秒雙聲道音訊的單次與二次分離,88200 個樣本均可讀且對齊;二次結果與伴奏相加重建混音的最大誤差約 7.5e-14。修正 Kim 配置以 other 命名伴奏的對應,避免推論完成卻找不到試聽來源。短測不代表整首歌曲的品質或長時間負載驗證。
recording.mjs 以 MediaRecorder 保存本輪歌聲,Web Audio 只將麥克風及選用的本機伴奏送進錄音 destination,不把伴奏接入音高分析或喇叭。預設 voice,mix 取已載入 cacheId 的 accompaniment,off 關閉保存。從頭開始唱先結束上一筆、載入伴奏並同步播放器,再在 PLAYING 開始;暫停/緩衝暫停錄製,續播/跳轉重新對齊伴奏。停止收音、結算、影片結束、卸載/換歌均結束當筆;直接點 YouTube 播放不另建錄音。
recording-store.mjs 將每秒音訊 chunk 與 metadata 以 IndexedDB transaction 原子寫入,完整結束標記 complete;崩潰時保留已提交片段。每段有獨立 ID,不覆蓋重唱前的錄音。空間或寫入失敗時保留記憶體音訊並提供下載;錄音成品與來源資料在完整結束後搬入歌曲庫下的「錄音」目錄,localStorage 分數仍獨立。分數勾選依清單位置區分同名紀錄,刪除前核對已渲染快照,避免另一分頁修改後錯刪。
驗證:36 項 JavaScript 測試通過。Edge/Chrome 使用實際 MediaRecorder + IndexedDB,440 Hz 麥克風與 660 Hz 伴奏解碼比對,確認 voice 不含伴奏、mix 同時包含兩者;測過每秒落盤、暂停續播、跳出伴奏範圍、停止收音後結算不重複、播完自動保存、重唱另存、off 不建立 MediaRecorder 並記住選擇、儲存額度不足時下載備份、重新載入後保留、下載及個別刪除。同名分數勾選刪除/全清除不影響錄音;原評分流程與分離試聽的瀏覽器回歸測試也通過。
預設未勾選「手動設定比例+自動微調」時自動平衡;勾選後,voice/backing 0–200% 各自作為 base gain,兩路各限 ±3 dB 修正。未勾選忽略 slider,採固定 base 與各路 ±6 dB 修正;選項在每輪開始時固定並保存於錄音 metadata,瀏覽器記住偏好。0% 始終靜音,voice-only 不連伴奏,off 不建立錄音器或混音圖。
recording-mix.mjs 在獨立錄音分支計算兩路 RMS,以 0.18 為目標電平;麥克風需現有音高偵測報告 voiced 且 RMS > 0.008 才做增益修正,不對低電平或未發聲訊號自動增強。AudioParam 平滑增益(下降 0.3 秒、上升 0.8 秒時間常數);混音經 compressor 與 ±0.98 峰值上限後進 MediaRecorder。此分支不更改收音 constraints,不修改評分用原始樣本或音高值。
驗證:39 項 JavaScript 測試通過;Edge/Chrome 實際錄音確認預設自動、手動 60% 人聲/80% 伴奏的可聽比例與即時修正、偏好保存、off 不建立錄音器,以及既有錄音保存/刪除功能。離線 Web Audio 雙路超載測試的輸出峰值低於 0.98;純函式測試涵蓋 ±6/±3 dB 界線、靜音維持為零、低電平/無穩定歌聲不增強。
新版錄製的音檔會標記 postDefaults: hall-echo-v1,開始後製時 A/B 兩組皆預設大廳、殘響 20%、尾音 1.8 秒、預延遲 25 ms、回聲 10%(300 ms/3 次/每次保留 40%/中央),兩組初始值完全相同。此標記只用於後製起始設定,錄音本身不加入效果。舊錄音沒有此標記,沿用前版起始值,不追溯加入回聲;不依錄製日期推測版本。已有後製設定的成品沿用其數值,包括明確保存的 0%。A/B「還原預設設定」回到系統預設(新清理與音準功能關閉);「重設全部人聲效果」仍可關閉所有效果。
「情境預設」提供貼近耳邊、木吉他、大廳一般流行、明亮流行、大廳慢板抒情、教堂、演唱會、夢幻八組。選取即帶入目前 A/B 組的殘響量、空間、尾音、預延遲、明亮度、寬度與回聲;另一組與 EQ、壓縮、柔化、音量、延時校正、剪輯保留。局部區段數值保留,其空間音色與回聲間隔仍沿用全域設定。手動改動空間參數後顯示「自訂空間效果」;切換組別會帶回數值與對應情境。兩個大廳情境皆有回聲 10%;夢幻為 12%/600 ms/3 次/每次保留 30%/左右交替,其餘關閉回聲。600 ms 是起點,未自動跟隨歌曲拍速。選取情境會停止舊片段試聽,按 A/B 重新試聽;重新合成才另存,不批次改寫任何舊錄音。
提供原版、房間、大廳、板式,以及新增的錄音室、小室、教堂、體育館、隧道、洞穴、浴室、夢幻空間。這些是合成的空間效果;新場景使用不同的尾音起伏、早期反射、反射間距與高頻衰減。選擇時帶入下列建議值,仍可微調;殘響音量需大於 0% 才能聽見。明亮度、寬度及殘響音量維持目前設定。
| 空間 | 建議尾音 | 建議預延遲 | 聽感 |
|---|---|---|---|
| 原版 | 0.8 秒 | 15 ms | 沿用舊版殘響,適合與既有成品比較。 |
| 房間 | 0.6 秒 | 10 ms | 緊密、短尾,帶少量近牆反射,增加自然空間感。 |
| 大廳 | 1.8 秒 | 25 ms | 寬廣、柔和,尾音逐漸鋪開,適合抒情歌。 |
| 板式 | 1.2 秒 | 15 ms | 明亮、密集,尾音較快出現,讓人聲多一層光澤。 |
| 錄音室 | 0.4 秒 | 4 ms | 貼近、柔暗的短尾,空間感收斂,保留清楚咬字。 |
| 小室 | 1.1 秒 | 12 ms | 溫暖、緊湊,密集反射讓歌聲較厚實。 |
| 教堂 | 4.2 秒 | 45 ms | 柔暗、緩慢鋪開的長尾,適合拉長音與莊嚴感。 |
| 體育館 | 3.2 秒 | 65 ms | 開闊、遠距,較晚的反射群帶出大型場地感。 |
| 隧道 | 2.6 秒 | 35 ms | 規律的一波波反射,能聽到沿著長通道延伸的尾音。 |
| 洞穴 | 3 秒 | 55 ms | 低沉、幽暗,不規則反射帶出深處回應的感覺。 |
| 浴室 | 0.7 秒 | 5 ms | 明亮、貼近硬牆,短促反射密集,適合聽鮮明的空間效果。 |
| 夢幻空間 | 3.6 秒 | 80 ms | 尾音慢慢浮起、綿長散開,營造漂浮感;不會改變音高。 |
新空間會隨成品保存,檔名、A/B 差異與還原也支援;原有四種空間沿用既有處理。
「片段試聽/A、B 比較」可指定剪輯前原始時間中的同一句(最多 30 秒)循環播放,選混音或只聽人聲。A(藍色)與 B(紫色)初始載入相同設定,之後各自調整;預設編輯 B。點 A/B 標籤或編輯區切換鈕,整個音量、延時、柔化、EQ、壓縮、殘響、回聲與局部效果面板會同步換色並顯示該組數值;離開前自動保留該組調整。無效欄位需先修正,避免切換遺失未完成輸入。「試聽目前設定」播放目前編輯的組別。準備完成後切換保持播放位置,以短交叉淡化避免切換聲;片段端點另有最多 3 ms 平滑。可選近似音量匹配,以雙聲道 RMS 降低較大聲的版本,不放大靜音,也不影響成品。比較不套用剪輯與淡入淡出,亦不新增錄音;選好 A/B 後按「重新合成」才另存目前組別;剪輯與淡入淡出共用。切換錄音/重整會清除比較暫存,停止比較保留已準備的兩組。首次合成仍需讀取完整來源及保留前段效果歷史,長錄音需等待。
編輯區固定標題旁的「還原 A/B 預設設定」還原目前組別到系統預設:原音、大廳殘響 20%+回聲 10%、音量 100%、校正 300 ms(AI 換聲成品 0 ms)、局部區段清空、四項清理/音準功能關閉。另一組、共用剪輯、試聽範圍與原錄音保留。重新合成另存會保留 A/B 各自草稿;只有另選錄音或重新整理才重新載入兩組設定。
試聽按鈕下方的「A/B 設定差異」即時並排顯示兩組不同的參數,A 藍、B 紫;相同項目不列出,差異越多表格越長。包含音量、延時、柔化、EQ、壓縮、殘響、回聲及依時間排序的局部區段欄位,缺少的區段標示「未設定」。拖動滑桿、切换選項、增刪區段或重設都會刷新;未完成或無效欄位先顯示提示,補齊後再列差異。表格比較目前編輯值,更新顯示不會中斷試聽或重算聲音;修改後需再按試聽,剪輯與淡入淡出共用且不列入差異。
殘響明亮度 −100~100 調整殘響返回路徑的高頻截止,0 沿用各空間預設;立體寬度 0~100% 調整脈衝響應的左右差異,0 集中、100 沿用原本寬度。回聲為獨立的有限延遲分支,可調 0~100% 音量、80~1000 ms 間隔、1~8 次重複、0~80% 每次保留音量,以及中央/左右交替。0% 保留音量只留下第一次回聲,避免無限回授;這些效果只處理歌唱者。
「局部效果」最多 20 個不重疊區段,各自覆寫殘響音量、尾音長度與回聲音量;其他參數沿用全域設定。區段以剪輯前完整時間為準。效果輸入在邊界平滑切換,已產生的殘響/回聲仍自然延伸,區段外的新聲音沿用全域設定。新欄位 reverbTone、echo、effectRegions 隨 vocalEffects 保存,舊錄音缺少時沿用原有聲音。全部效果可重設、重複編輯不累加,檔名附新效果摘要。
後製成品的錄音清單、選單與 WAV/MP3 下載名稱會加入 _人聲後製,並標示已套用的人聲/配樂音量、局部音量段數、EQ、壓縮、殘響及既有柔化/延時後綴。名稱依保存的設定產生,未合成的調整不影響名稱;原歌名及音檔資料不改寫,反覆後製不累加舊後綴。既有成品有保存設定時也適用。
「人聲進階後製」加入局部音量、三段 EQ(200 Hz 低架/1.5 kHz 峰形/5 kHz 高架,各 ±12 dB)、輕度/中度動態壓縮及 0–100% 殘響;新版錄製的音檔,A/B 後製皆預設大廳殘響 20%+回聲 10%,舊錄音沿用原有設定。局部音量使用剪輯前的完整錄音時間,以秒數指定不重疊區段,0–200%,邊界最多 10 ms 平滑;已剪輯成品的「目前播放位置」會自動換算,改延時後需核對區段。順序為降噪/齒音 → 呼吸聲降低 → 音準修正 → 柔化 → EQ → 壓縮 → 局部音量 → 殘響 → 原錄音平衡/音量 → 輸出峰值保護 → 剪輯/淡入淡出。人聲效果不套用配樂與和音;剪輯和淡入淡出則作用於整份成品。
效果保存為版本化 vocalEffects 設定,重選成品自動帶回;每次重用原始歌聲,效果不累加。殘響提供原版/房間/大廳/板式空間、0.2–10 秒尾音與 0–500 ms 預延遲;切換空間先帶入建議值,仍可個別調整。使用固定種子的脈衝響應;原版預設仍保留原來的 0.8 秒響應,不改變舊成品的效果。只聽人聲也沿用已保存的效果和剪輯。
「剪輯與淡入淡出」可輸入保留起訖秒數,或用試聽播放器位置設定;結束留空表示保留至尾音結束,明確指定結束會一併裁掉其後殘響。淡入/淡出各 0–30 秒,合計不可超過保留長度。按重新合成另存新版本,名稱附上剪輯與淡入淡出設定。設定保存為 postEdit,起訖永遠以剪輯前完整錄音為準;sourceSeconds、乾淨歌聲與時間資料獨立保留,刪除上一版仍可重設剪輯後合成完整版本(混音仍需保留歌曲配樂)。局部音量和重新評分仍使用完整原始演唱範圍,不因剪輯更改評分。重設人聲效果與剪輯後重新合成即可撤回;既有錄音缺少新設定時視為關閉。
驗證包含單元測試與真實 Web Audio 合成測試:局部音量/靜音、EQ 頻段、壓縮動態、殘響尾音與重現性、舊殘響資料完全一致,以及配樂不套用人聲效果。剪輯瀏覽器測試另檢查取樣邊界、淡入淡出、另存/重選、重複編輯、刪除上一版後還原、只聽人聲及手機版面。真人歌聲聽感仍需試聽調整。
「只聽人聲」可單獨試聽所選錄音的歌唱者,沿用已保存的音量、延時與柔化設定,不加入配樂/和音,也不另存錄音或讀取歌曲庫配樂。一般「試聽」可切回完整成品。未重新合成的設定不會影響成品試聽;舊混音若缺乏原始歌聲,會停用人聲試聽。純歌聲錄音直接播放已保存的成品。
後製提供歌唱者與配樂/和音各自 0–200% 的音量調整。100% 沿用原始錄音的平衡,自動修正後再套用音量倍率,最後保留峰值保護;0% 從開始即靜音。按重新合成才套用,配樂與和音共用倍率,純歌聲錄音停用配樂滑桿。
新版另存成品同時保存自己的原始歌聲、播放時間/基準快照、原始平衡設定,以及目前音量、延時和柔化設定,可直接繼續後製。每次從未處理的歌聲重新計算,設定取代上一版,不累加柔化、增益或延時;另存前以同一 IndexedDB transaction 寫入成品與來源,再搬至歌曲庫。刪除上一版仍可編輯新版,但配樂仍依賴歌曲庫中的同版本音軌。單獨下載的 WAV/MP3 不包含編輯資料;舊成品若未保存來源,仍需選回原始錄音。
驗證:57 項 JavaScript 測試及錄音/搬存瀏覽器測試通過。合成音訊確認獨立音量倍率、雙路靜音、重複後製結果一致、關閉效果可還原原始重混結果,以及跨瀏覽器保存後製設定與原始歌聲。未改寫使用者既有錄音。
新版錄音保存成品、獨立麥克風音軌與當次評分/播放時間快照(錄製中暫存 IndexedDB,停止後搬入歌曲庫的「錄音」子目錄)。頁面下方可填總延時:正值提前歌唱者,負值延後;重新評分保留原設定及遮罩,重新混音另存 WAV、不覆蓋原檔。伴奏及和音同步、共用音量。原始與合成錄音均可透過受 Origin/token 保護的 localhost /recordings/mp3,由 FFmpeg 轉 192 kbps MP3 下載;不傳雲端,暫存檔自動清除。舊錄音缺乏來源資料時只開放轉檔。更新本機工具後需重啟。
評分取樣以最接近 i × step 基準時間的觀測為準,不再以每個 100 ms 格子最後一次觀測覆蓋,避免換音時出現時間偏差。此規則同時用於即時評分與錄音後重評;權重、難度與八度規則不變,舊基準不需重新分離。
錄音後重評改從保存的乾淨歌聲解碼,由本機 Web Worker 重新擷取置中音高(20 ms hop)。歌聲先按延時移動,再依重混 segments 映射到歌曲時間,避免與即時播放器時間戳混用;分析緩存在該錄音 metadata。顯示同音檔 0 ms 的進拍分數供比較,沒有預設最佳補償或調分。
recording-archive.mjs 透過既有 Origin/token 保護的 localhost API,保存到目前歌曲庫的 錄音/<recording UUID>/。metadata.json 保存原始基準、播放位置、音高資料和重評结果;mix.webm/mix.wav、voice.webm(依錄音 MIME)保存音檔,MP3 轉檔另留 export.mp3。原始來源與重新合成成品各自獨立。
瀏覽器每秒仍寫入 IndexedDB,完整結束後以分段封包搬存。先驗證音檔大小、完成暫存目錄與原子提交,再移除瀏覽器副本;失敗保留原檔供重試。開啟/重新整理錄音時自動搬存既有完整錄音;Chrome 和 Edge 需各開一次以搬出各自舊資料。已搬存資料由本機工具共用,重評更新磁碟 metadata,不改原錄音基準。
清單提供單筆與全部刪除,先確認再刪除錄音及後處理來源,不涉及歌曲分離音軌或基準。刪除記號避免尚未更新的瀏覽器舊副本把錄音搬回。目錄只接受 UUID 與本工具 manifest;檔案讀寫限制在目前歌曲庫,切換位置後過期操作會被拒絕。測試涵蓋搬存完整性、失敗回復、跨瀏覽器、重評/MP3 保存、刪除與全刪除。
四項預設皆關閉,只處理保存的原始歌聲;A/B 各自調整、差異表同步顯示,另存保存設定與原始人聲。降噪會從安靜、無音高的空檔估計底噪並做頻譜衰減,找不到空檔時略過;齒音使用高頻動態衰減,可調強度及 3–10 kHz 偵測頻率;呼吸聲依無音高、頻帶能量、短區段及鄰近歌唱位置辨識,不是辨識文字的 AI,可能誤判氣音或子音,可用局部音量補調。音準修正提供最近半音/錄音當時原唱基準,後者依保存的播放段落與歌聲校正量找目標並保留演唱八度,不修正休息、不計分範圍或相差超過兩個半音的音。強度 0–100%、修正速度 20–500 ms、保留顫音開關可分別調整。速度不是播放延遲。
音準合成採用 TD-PSOLA 的音高同步重疊相加思路(Praat 官方方法說明),輸出取樣率、取樣數、聲道數與原音完全相同;不以變速、裁切或補尾端來對齊。顫音保留是修正平均偏音,並不保證每種滑音/氣聲唱法都能自然修復。所有分析在瀏覽器 Worker 執行,不啟動 GPU 模型,不上傳歌聲;處理進度顯示於試聽或合成狀態欄。A/B 最多快取兩份清理後的人聲。評分仍分析原始演唱,不使用修正後音準。
驗證:tests/recording-repair.test.mjs 量測底噪衰減、低頻保留、呼吸衰減、三種取樣率的音高、顫音及基準時間映射;tests/recording-repair-browser-check.mjs 驗證 Worker、A/B 各自參數、實際試聽、原音保存、IndexedDB 重開、檔名及初始化。
播放器下方選原調或 −12~+12 整數半音。新歌準備時一起建立,已載入歌曲按「建立/載入此 Key」。local-library.mjs 為非零 Key 使用原 cache ID 加 _key_m2/_key_p1 等後綴;原調 ID 相容既有歌曲。pitchShift、原曲名稱和來源 ID 存在 reference.json,原調分離音軌共用為製作來源,每個變調版本保存獨立音軌。錄音與分段草稿使用該版本 cache ID,原始歌聲、既有成品不追溯變調。刪除版本只刪該版本,原調與其他 Key 保留;同片同範圍的評分遮罩仍共用。
tools/key_shift_worker.py 用 FFmpeg 的 Rubber Band 做 pitch-only 處理(tempo=1),保留時長並驗證完整解碼;不重跑聲曲分離。沒有原調音軌時先建立原調,再製作目標 Key。FFmpeg 須包含 rubberband filter,失敗不發布半成品。評分基準頻率乘以 2 ** (pitchShift/12),旋律時間點、節拍與遮罩不移動。即時音高/重評支援對應音域,禁止跨 Key 更換重評基準。
key-playback.mjs 為非零 Key 接管帶唱:YouTube 原聲靜音,影片速度保持 1,本機音軌跟隨播放、暫停、緩衝和跳轉。「原唱+伴樂」播放變調 vocals+accompaniment;「只有伴樂」播放變調 accompaniment,主唱模式另加 backing。整首、分段播放/循環/錄音共用此輸出,試聽與試合從錄音所屬版本取伴樂;卸載/回原調恢復進入前的靜音狀態。
驗證:node --test tests/song-key.test.mjs、node tests/key-browser-check.mjs、node tests/key-helper-check.mjs(臨時歌曲庫、需 FFmpeg)、python -m unittest discover -s tests -p test_key_shift.py(合成聲音驗證升降音高、長度與起尾時間)。
播放器的「影片來源」可選 YouTube 或本機 MV。本機支援 MP4/M4V/MOV/MKV/WebM,最大 2 GB、15 分鐘,需含音訊。匯入會在設定的歌曲庫 .local-mv 保存可播放的 MP4 副本,不變更原檔、不上傳雲端;不相容的視訊編碼會自動轉換。檔案內容 SHA-256 作為獨立歌曲 ID,同檔重複匯入沿用,不與 YouTube 混用。
載入後按「準備歌曲基準」,可使用相同的分離選項、評分、整首/分段錄音、試合、升降 Key 與後處理。後續從歌曲庫點選即載入影片和該 Key 的基準。建立基準前亦可在「已匯入的 MV」重新選擇。刪除歌曲基準保留 MV 副本及原始檔;手動移除副本後需重新匯入才能播放。
影片只經 loopback 傳給本機工具;媒體播放以限定影片的暫時票證與 HTTP Range 支援拖曳,未授權請求不能取得影片。