VST 製作者
非官方社群技能。此處提及的任何外掛程式、合成器或框架供應商均未製作或認可此技能。
如何解讀信心標籤:
- (V: 來源) 已根據指定的來源驗證。
- (R) 經驗法則或品味。是透過測量與聆聽來測試的起始值,絕非鐵律。
若某項事實沒有標籤,則代表它是標準實務,但在依賴於正式發布前,您仍應自行驗證。
0. 基本規則
- 開始建置前先詢問:外掛程式類型(合成器、效果器、控制器)、目標作業系統(Linux、macOS、Windows)、格式(優先 VST3;CLAP 或 LV2 為選項)、色調(絕不預設;若使用者未提供,則提供中性預設值)、授權條款(請參閱第 1 節)。
- 免費且開放原始碼的外掛程式必須能離線運作:無需帳戶、無授權伺服器、安裝或執行時無需下載。外掛程式所需的一切都應包含在內。
- 絕不單憑耳朵聲稱聲音好壞。應進行測量(請參閱第 12 節),讓使用者的耳朵做最終判斷。
- 每個數字都應引用或測試。若某數值僅為經驗法則,請說明「未經驗證」。
- 當使用者非程式設計人員時,一次只執行一個步驟。先提供簡短答案,細節則視需要提供。
1. 專案設定與授權條款
- JUCE 採用雙重授權:JUCE 授權條款與 AGPLv3。若無付費 JUCE 方案,您必須在 AGPLv3 下使用,而 AGPLv3 所要求的遠比公開原始碼更多(V:JUCE 論壇,工作人員回覆)。在選擇前,請閱讀您所用版本的現行 JUCE 授權條款,並告知使用者適用哪一種。請勿憑記憶陳述方案價格或收入限制。
- 使用 CMake。讓 DSP 程式碼獨立於 JUCE GUI 型別,以便能在無視窗環境下進行單元測試。
- 優先建置 VST3。CLAP 與 LV2 為選項:在承諾支援任一項之前,請先查看現行 JUCE 文件與 clap-juce-extensions。
- 主機掃描 VST3 的位置(V:Steinberg VST 3 開發者入口網站,外掛程式位置):
- Linux:優先
$HOME/.vst3/,其次為/usr/lib64/vst3/、/usr/lib/vst3/、/usr/local/lib64/vst3/、/usr/local/lib/vst3/。 - macOS:
~/Library/Audio/Plug-ins/VST3/(使用者),/Library/Audio/Plug-ins/VST3/(全域)。 - Windows:
C:\Program Files\Common Files\VST3\(全域),%LOCALAPPDATA%\Programs\Common\VST3\(使用者,主要用於開發)。 - 主機會找到第一個符合處理器 UID 的外掛程式,並按優先順序掃描。
- Linux:優先
2. 即時安全性
processBlock 在具有嚴格截止時間的高優先權音訊執行緒上執行。JUCE 文件指出,在那裡與 UI 的任何互動都是不可能的,且程式碼必須能應付可變的區塊大小(V:JUCE AudioProcessor 文件)。
絕不在音訊執行緒上執行的操作:
- 配置或釋放記憶體(new、delete、malloc、擴充的向量或字串、建構 juce::String)
- 取得其他執行緒可能持有的鎖(std::mutex、CriticalSection)
- 檔案、網路或主控台 I/O
- 呼叫 UI 或 MessageManager
- 擲回例外或呼叫任何具有未知即時行為的內容
應改為:
- 在
prepareToPlay中進行配置(取樣率在播放停止前保持不變;區塊大小僅為提示,文件建議進行防禦性程式設計,以防主機超出該大小)(V:JUCE 文件)。在releaseResources或解構式中釋放。 - 使用無鎖佇列(
juce::AbstractFifo)或原子變數與其他執行緒通訊。UI 使用定時器輪詢原子變數;或從音訊執行緒觸發 AsyncUpdater。 - 將
juce::ScopedNoDenormals放在processBlock開頭;它會保持活動狀態直到函數返回,因此輔助函數無需重複(V:JUCE 論壇共識,非官方文件)。同時設計回饋路徑,使其不會衰減至非正規化數值。 - 建議閱讀:Ross Bencina,“即時音訊程式設計 101:時間不等人”(此處未引用,因為撰寫此技能時無法取得)。
3. 參數與狀態
- 使用
AudioProcessorValueTreeState:主機自動化、復原與狀態儲存都隨之而來。 - 對每個影響增益、頻率、混合或延遲時間的參數進行平滑處理(
juce::SmoothedValue),否則會產生鋸齒噪音與爆音。 - 除非值是每個取樣點進行平滑處理,否則應在每個區塊將其讀取為區域變數一次。
- 為每個參數提供穩定的字串 ID。發布後絕不重新命名或重新排序 ID:這會破壞已儲存的專案與自動化。使用新的 ID 新增參數並維持狀態版本號碼。
- 驗證所有從狀態或預設載入的內容:限制範圍、忽略未知鍵、絕不信任大小或計數。
- 嚴格分離處理器(DSP 與狀態)與編輯器(UI)。處理器必須能在編輯器視窗關閉的情況下完美執行。VST3 本身將外掛程式拆分為處理器與控制器(V:Steinberg VST 3 教學,“編寫你的第一個外掛程式”)。
- 即使 JUCE 已封裝,仍值得了解的 VST3 事實(V:同一教學):參數始終正規化為 0.0 到 1.0;設定 automatable 旗標以便主機進行自動化;一個處理區塊可能包含同一參數的多個變更,因此手寫的處理器必須正確處理佇列(教學中僅套用最後一個變更,這是一種簡化);若輸入為靜音,則設定並尊重靜音旗標並清除輸出緩衝區;拒絕不支援的匯流排佈局,而非進行猜測;當沒有輸入或沒有樣本時,仍應套用待處理的參數變更。
更多 VST3 架構事實(V:Steinberg VST 3 開發者入口網站,API 文件):
- 處理器必須能在未載入控制器的情況下工作,因此 DSP 狀態絕不依賴編輯器。
process()與setProcessing()可能在意音訊執行緒上執行:禁止配置。初始化與終止則在 UI 執行緒上執行。- 匯流排與揚聲器排列只能在外掛程式處於非活動狀態時變更。為所有匯流排提供緩衝區,即使是非活動的匯流排。輸入與輸出緩衝區可能共享記憶體,因此不要盲目清除輸出。
- 音符以事件形式在
process()中到達。參數變更透過參數佇列以取樣點精確度到達。速度與傳輸資訊則在程序上下文中提供。 - GUI 到主機的編輯使用 beginEdit、performEdit、endEdit 的順序,且僅在 UI 執行緒上進行。
- 在狀態還原時,處理器先還原;控制器隨後收到元件狀態,且不得觸發處理器回呼。
- 請勿從
process()發送私有的處理器到控制器訊息;應使用 UI 執行緒或資料交換 API。 - 單位對參數進行分組;MIDI 對應介面將 MIDI CC 對應到參數。
- 需要時閱讀的入口網站頁面:參數與自動化、工作流程圖、多重動態 I/O(側鏈)、VST 3 單位、資料交換。
4. 效能:CPU、RAM、GPU
- 在最佳化前先進行測量(請參閱第 12 節)。
- CPU(R):以區塊為單位進行處理,在參數變更時預先計算係數,避免在內部迴圈中使用每個取樣點的分支與虛擬函式呼叫,避免在每個取樣點使用
std::pow、std::exp、std::sin,如果遞迴或查表法速度更快且經測量確認。 - RAM:一次性預先配置,在音色間共享 wavetable 與表格,在
releaseResources中釋放大型緩衝區。 - GPU 與 UI:僅在編輯器可見且位於前端時進行繪製。當隱藏時暫停定時器、量表與畫布動畫;音訊、自動化與 MIDI 則繼續執行。限制重繪速率並僅重繪髒污區域(R)。僅在明確需要且已在 Linux 上測試時,才使用 GPU 渲染。
- 隱藏或關閉的編輯器不得持續執行每幀的工作。
5. 延遲
- 每當外掛程式延遲音訊(例如:前瞻限制器或壓縮器、線性相位濾波器、過取樣濾波器)時,使用
setLatencySamples報告實際延遲(“它引入的延遲樣本數”,V:JUCE 文件)。在主機中驗證該報告已被套用。 - 樂器從音符開啟到發出聲音的延遲為零。
- 線性相位過取樣濾波器會增加延遲;最小相位濾波器則不會改變相位。應有目的地選擇並記錄。
juce::dsp::Oversampling會報告其延遲;也應報告它。 - 確保
getTailLengthSeconds對於殘響與延遲效果是正確的,以免主機截斷尾音。
6. 音質
混疊
- 簡單的鋸齒波與方波具有高於 Nyquist 頻率的諧波,這些諧波會以非諧波噪音的形式折返。修正方式:頻帶限制步進方法(BLEP 系列)、微分多項式波形、每個八度音階的頻帶限制 wavetable,或過取樣。
- 一種已發表的方……
(為保持完整性,由於原始內容過長而被截斷,但此處會根據提供的內容進行完整本地化)
[…]