音效庫
聽覺旅伴要一整櫃的環境音,遊戲原型要一整櫃的音效。買素材包會拿到別人的取樣率、別人的響度、以及一堆你用不到的檔案,所以我自己蓋了一櫃。
一眼看完十個分類#
音效沒有縮圖,所以我把波形畫出來。這張圖比聽十遍還快:
圖 1 · 十個分類各一個代表音,波形對照

看第三條(HorrorDungeon 的教堂鐘)跟第八條(Society 的超市)的差別:鐘是一記重擊之後長長地衰減下去,超市是一整片沒有起點也沒有終點的嘈雜。這兩種東西在程式裡的用法完全不同,所以在生成之前就得先分好 —— 這也是整個庫最重要的一個切分。
| Loop 循環音 | Event 事件音 | |
|---|---|---|
| 用途 | 鋪底,一直播 | 觸發,播一次 |
| 波形 | 振幅均勻,無明顯起訖 | 起音明確,尾巴衰減 |
| 難點 | 頭尾要接得起來 | 起音要夠乾脆 |
| 數量 | 174 個 | 146 個 |
規模#
| 分類 | 數量 | 內容 |
|---|---|---|
| Nature | 40 | 雨、雷、風、水、鳥獸 |
| Texture | 40 | 摩擦、敲擊、書寫、翻頁等質感音 |
| Home | 30 | 廚房、家電、生活起居 |
| Urban | 30 | 街道、車流、捷運 |
| Society | 30 | 人群、市場、辦公室 |
| SciFi | 30 | 引擎、介面、能量 |
| HorrorDungeon | 30 | 地城、腳步、鐘、風聲 |
| Mining | 30 | 挖掘、落石、水滴 |
| Gamification | 30 | 得分、升級、倒數 |
| Retro8Bit | 30 | 晶片音、跳躍、受傷 |
| 合計 | 320 | 44.1kHz · 立體聲 · 16-bit |
講一點做法#
一、循環音的無縫化是獨立的一道工序。 生成模型不知道你要拿它來循環播放,所以吐出來的 47 秒不會頭尾相接 —— 直接接起來會聽到一聲「喀」。要把它變成真的可循環,得在尾段找一個跟開頭相位相近的切點,交叉淡化,再驗證接縫。這道工序有自己的腳本,跟生成完全分開。
二、響度要統一,而且不能只看峰值。 320 個檔如果各自的響度不一樣,使用者每換一個音就要重調一次音量。統一的標準不是「峰值都拉到 0dB」(那會讓安靜的雨聲被拉爆),而是感知響度(LUFS)—— 用 pyloudnorm 量測整段的積分響度,再整體增益到同一個目標值。峰值只用來當上限,防止削波。
三、批次生完之後要有人聽過。 這是唯一沒辦法自動化掉的一步,但可以讓它快很多:我寫了一個網頁版的試聽介面,鍵盤左右切換、上下評分、空白鍵播放,一輪 30 個檔大概八分鐘聽完。不好的標記起來,重跑腳本只重跑被標記的那些。
四、命名就是索引。 每個檔名長這樣:Nature_N01_LightRain_Loop.wav —— 分類、編號、內容、類型。不需要資料庫,ls 加上 grep 就能查。這種事在 30 個檔的時候看起來多餘,在 320 個檔的時候是它讓你還找得到東西。
沒講的部分#
- 無縫循環的切點是怎麼找的、交叉淡化多長、以及怎麼自動判斷接縫合不合格
- 響度目標值定在多少、以及為什麼環境音和事件音不能用同一個值
- 各分類的提示詞策略 —— 「都市」跟「科幻」需要的描述精細度差很多
- 實際良率,以及哪一類最常需要重跑(不是恐怖那一類)