Community生產力與協作github.com

music-skill

從終端機創作、檢查與理解音樂,專門為無法聽見聲音的代理程式設計。當需要製作音樂(例如浩室或鐵克諾曲目、節拍、循環、影片或人聲底墊、指定長度、速度或調性的音樂、音軌分軌或MIDI),或者需要了解一段音訊的內容(例如「BPM多少?」、「這是什麼調?」、「高潮在哪裡?」、「為什麼這個混音聽起來很糊?」),或者在音樂輸出前需要進行品質檢查(如LUFS響度、真實峰值、削波、單聲道相容性)時使用。也適用於分析節奏為何有效(如切分音、搖擺感、微時值、聲部進行、段落鋪陳與高潮),以及檢查生成式模型所製作的音樂。

music-skill 是什麼?

music-skill 是一個專為無法聽覺的 AI 代理程式設計的命令列技能,使其能夠從終端機創作、解析與交付電子音樂。它包含兩個主要腳本:`banger.py` 用於生成四拍子(four-on-the-floor)風格的電子音樂,如深層浩室、科技浩室或旋律鐵克諾;`listen.py` 則用於分析任何音訊檔案,提供 BPM、調性、響度(LUFS)、真實峰值、頻譜平衡與時間軸等數據。 此技能的核心是基於規則的搜尋引擎,而非機器學習模型,其所有規則均源自節奏與音高感知的學術研究。它能保證完全相同的種子與設定產生完全相同的結果,並提供 MIDI、分軌音訊、文字樂譜與 JSON 格式的規則評分。使用者透過閱讀文字化的節奏圖案與檢查生成的頻譜圖來「聆聽」音樂。 此技能特別適合用於生成精確長度與調性的背景音樂、製作影片或人聲底墊、分析不明音訊的結構,以及在上傳前確保音訊符合響度與動態範圍的業界標準。它支援執行檢查 (`check` 命令),若音訊檔案的響度、真實峰值或 BPM 不符合指定目標,則會以非零狀態碼退出。對於所有生成式音訊輸出,`look` 命令是必備的初步檢查步驟。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/kylefritz/music-skill/tree/HEAD

Installed? Explore more 生產力與協作 skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

music-skill 是做什麼的?

腳本位於此檔案旁邊的 scripts/ 目錄中;下方將其寫為 $S,但在每個命令中必須拼寫出絕對路徑,因為 shell 變數不會在不同的 Bash 呼叫之間傳遞。

你無法聽見聲音,因此每個步驟都會將音樂轉換為你可以閱讀的內容:文字化的節奏模式、可供檢查的數值,以及一張你需要觀看的圖片。 創作一首曲目的流程是:種子 → 閱讀樂譜 → 渲染 → look(查看)→ 修正。理解音訊則是:look(查看)→ 閱讀時間線與圖表 → 判斷。交付前需要執行 check(檢查),這樣「響度正確且不會削波」就成為一個可確認的事實。

需要安裝 uv 和 ffmpeg。每個命令都以 uv run --no-project --with numpy --with scipy --with pillow python -I <script> … 的形式執行,下文簡寫為 RUN。

創作一首曲目:banger.py

RUN $S/banger.py --seed 4242 --out <scratch>/b4242

一首 72 小節的浩室或鐵克諾曲目大約需要 10 秒鐘完成:會產生 track.wav(48 kHz 立體聲,-14 LUFS)、track.mid、score.txt 和 score.json。相同的種子和選項總是會產生完全相同的檔案。

想要的功能選項
一種風格--style deep-house(120-124 BPM),tech-house(124-128),peak-techno(130-136),melodic-techno(122-126)
速度或調性--bpm 124,--key A,--mode minor(或 dorian,phrygian)
長度--bars 24(任何從 8 開始的偶數),或 --seconds 30:它會自動選擇小節數並調整速度,使最後一小節提前 2.5 秒結束,讓殘響(reverb)能準時消退
人聲底墊--lufs -22 --mute lead(也可以試試靜音 clap)
給 DAW 或混音檢查用的分軌--stems 會寫出 stems/<layer>.wav;track.mid 始終會產生

小節數決定了曲目的結構:8-10 小節是一個循環(loop);12-22 小節是前奏、高潮、尾奏;24-46 小節會添加一個間奏(breakdown)和一個銜接段(build-up),位於兩個高潮之間;48 小節及以上是完整結構,包含一個律動樂段(groove section)和 8 小節為單位的段落。

在渲染更多內容之前,先閱讀樂譜。 它會將節奏模式列印為文字:

seed 4242  Melodic techno  122 BPM  G minor  swing 1%  chords: pluck
       1...2...3...4...
kick   X...X...X.X.X...
clap   .o..X.......X...
hat    x.X...X.x.X...X.
bass   .....ORO.O.O3RRR
chords ...X............  i7 Gm7 | bVII7 F7 | bVI7 Ebmaj7 | iv7 Cm7
lead   47244.42.22..442 .3315.553.5.3557
perc   fit  74%   1293 patterns tried   weakest: Evenly spread 52%, Clear mix 20%
  • . 休止符,o 弱音,x 中音,X 強音。
  • 貝斯(Bass):R 根音,5 五度音,O 八度音,3 三度音。
  • 主旋律(Lead):0-9 的音階音級,跨越兩個小節。
  • fit 表示該聲部在其規則下的符合程度;weakest 列出了未達標的規則。

若要挑選種子,可以先透過文字進行試聽:執行 python3 $S/groove.py --seed N 只會執行搜尋(0.5 秒,不產生音訊,無需依賴項)。嘗試幾個種子,閱讀和弦與主旋律,然後渲染你最中意的那一個。你無法判斷「聽起來好不好」:直接說明這一點,並將檔案交給使用者。

一首曲目的產生方式

此方法源自 Banger Lab。這是一個搜尋過程,而非模型,且每一條規則都來自節奏或音高感知的研究。

  1. 滾動(Roll)。 種子會決定風格、速度、調性、音階以及目標:例如每小節的開合鈸(hats)數量、切分音的程度、不同和弦的數量。
  2. 猜測(Guess)。 每個樂器先從一個隨機的 16 步節奏模式開始。
  3. 測試(Test)。 針對每一步的變更(新增、移除、滑動、變大聲、變小聲),根據該樂器的規則進行評分,並同時測試少量隨機的兩步跳躍。保留得分最高的一種變更。
  4. 鎖定(Lock)。 當沒有任何變更能獲得更高分數時,該聲部即完成,然後在它的基礎上產生下一個樂器。順序為:大鼓(kick)、小鼓(clap)、開合鈸(hats)、開鈸(open hat)、打擊樂(percussion)、貝斯(bass)、和弦(chords)、主旋律(lead)。每個層級會進行四次隨機初始,並保留最佳結果。
  5. 聆聽(Listen)。 banger.py 會獨立渲染每種樂器,測量其能量在六個頻段中的分佈。然後進行第二輪處理,重新調整開合鈸、打擊樂、貝斯、和弦與主旋律,以避免不同聲部在同一時間步(step)佔據相同頻段。
  6. 編排(Arrange)。 各個聲部被組合成樂段:在每 4 小節和 8 小節的結尾加入過門(fills);在間奏(breakdown)部分有一個低通濾波逐漸打開;在銜接段(build-up)有軍鼓滾奏(snare roll)和 riser 效果;短暫的一拍靜默後,迎來高潮(drop)。

節奏的奧秘:規則

無論你是透過何種方式創作或編輯音樂(手工編寫節奏模式、MIDI、或對音樂模型的提示),都可以利用這些規則。score.json 檔案中包含了針對某首曲目的每條規則的評分與來源。

聲部規則來源
大鼓(Kick)每個強拍上都要有;最多 0-2 個額外的大鼓,且放置在強拍之前;絕不能連續兩個強拍Butler 2006
小鼓(Clap)在強拍 2 和 4 上要大聲,在強拍 1 和 3 上要小聲;額外的小鼓要輕聲且位於弱拍十六分音符上Butler 2006; Witek 2014
開合鈸(Hats)位於弱拍(off-beats),即大鼓之間;均勻分佈;在小節的前半與後半保持相同模式;強聲與弱聲交替出現Butler 2006; Toussaint 2005
開鈸(Open hat)位於兩個大鼓的中間點,絕不和鼓或小鼓同時出現Butler 2006
打擊樂(Percussion)均勻分佈在大鼓和小鼓沒有出聲的地方,包含 25-50% 的輕聲幽靈音符(ghost notes)Toussaint 2005; Witek 2014
貝斯(Bass)在大鼓沒有出聲的地方演奏;60-90% 的時間演奏根音(或其八度音),其餘時間用五度或三度音增添色彩Plomp & Levelt 1965; Krumhansl & Kessler 1982
和弦(Chords)第 1 小節是主和弦;根音以級進、三度或四度進行;每個聲部以最短的路徑移動到下一個和弦Krumhansl & Kessler 1982; Tymoczko 2011
主旋律(Lead)在強拍上演奏和弦音;從不演奏比和弦音高一個半音的音符;以小跨度進行為主;第 1 小節營造疑問(結束在非主音上),第 2 小節以相似的節奏回答(結束在主音上);在和弦出現的間隙中演奏Plomp & Levelt 1965; Huron 2001; Caplin 1998
所有聲部中度切分音:一些音符落在弱拍上,並跳過一個強拍。切分太少會很生硬,太多則會失去節奏感Witek et al. 2014
時值(Timing)搖擺感(swing)和推拉感(push/pull)每種樂器控制在 12 毫秒以內(開合鈸稍晚,小鼓稍早)。更大的偏移會降低律動評分Davies et al. 2013
混音(Mix)兩個聲部在同一時間步佔據同一頻段會相互模糊;同一時間步最多不超過 4 個聲部同時出聲Plomp & Levelt 1965
結構(Form)間奏(breakdown)、銜接段(build-up)和高潮(drop):移走大鼓和貝斯,提升緊張感,然後再把它們帶回來Solberg & Dibben 2019; Butler 2006

每個音符都來自同一個音階,且大鼓調音至主音。這就是為何任何種子都能保持在調性內的原因。規則之間的權重是簡化過的,並非根據聆聽數據擬合,因此 fit 值僅用於對一首曲目內的不同節奏模式進行排序,而非跨曲目的品質評分。

聆聽:look

RUN $S/listen.py look TRACK --sheet <scratch>/sheet.png

適用於任何 ffmpeg 能夠解碼的檔案,包括影片的聲音以及生成式模型產生的音樂。它會輸出速度、調性、響度、真實峰值、平衡、立體聲寬度、警告訊息以及一個時間軸:

track.wav  2:24.1  122.0 BPM (strength 7.9)  G minor (score 1.62; next Eb major 1.61)
  loudness -14.0 LUFS  true peak -1.3 dBTP  range 9.3 LU  peak-to-loudness 12.7 dB
  balance, dB under the loudest band  sub -2  bass 0  low mid -8  mid -17  high -24  air -27
  timeline, 15.7 s windows (8 bars): loudness, then each band in dB against its level over the whole track
    start     LUFS        sub    bass low mid     mid    high     air
     0:47.2   -12.6         +2      +2      +1      +2      +1      -2
     1:03.0   -21.1        -29     -12      +1      -7      -7      -6
     1:18.7   -20.5        -33     -12      +1      -1      +3      +6
     1:34.4   -12.6         +2      +2      +1      +2      +1      -0

從時間軸上讀取結構。次低頻(sub)和低頻(bass)下降 20-30 dB 表示間奏(breakdown,大鼓和貝斯消失了)。高頻(high)和空氣感(air)爬升而次低頻保持不變表示銜接段(build-up)。所有頻段同時恢復是高潮(drop)。然後閱讀圖表(波形圖、頻譜圖、六個頻段通道、響度曲線):riser 效果是一條對角線;大鼓是底部一列明亮的點;一片連續無空隙的色塊表示缺乏動態的混音。在描述某個時刻時,請參考圖表軸線上的時間。

以下是根據 24 首已知答案的曲目進行測量的可信度:

  • 速度(Tempo):24 首中有 24 首的誤差在 0.2 BPM 以內。它偏好 70-190 BPM,因此在處理其他素材時可能會出現半速或倍速的判斷。當強度(strength)低於 2 時,表示沒有穩定的節拍:請註明 BPM 僅為猜測。
  • 調性(Key):24 首中有 19 首的主音判斷正確,在處理短音訊或稀疏音訊時可靠性較差。大調 vs 小調的判斷準確度較低,且無法區分教會調式(modes)。當得分最高的兩個調性分數接近時,工具會進行提示;請同時報告這兩個結果。
  • 響度(Loudness)和真實峰值(True Peak):與 ffmpeg -af ebur128=peak=true 的結果一致,誤差在 0.1 以內。

分軌之間的比較:mix

RUN $S/listen.py mix <scratch>/b4242/stems

此命令會列出每個分軌的響度及其能量所在位置。然後顯示互相重疊最多的分軌對(同一頻段、同一時間點),以及相對於最大聲分軌顯得非常安靜的分軌。若一對分軌的重疊度超過 60%,表示有兩個聲部在同一個空間中互相干擾:需要透過調整時間、音高或音量來移開其中一個。

需要達標的數值與檢查

目標數值
獨立的曲目(串流平台會將其標準化到附近的值)-14 LUFS 整合響度
網路影片或 podcast 的最終混音-16 LUFS
人聲底墊大約 -22 LUFS
真實峰值,始終-1 dBTP 或以下:有損編碼會導致過衝(overshoot)
峰值與響度比低於 7 dB表示過度限制(over-limited):聽起來扁平且令人疲勞
120 Hz 以下的立體聲相關性低於 0.6低頻在單聲道下可能會消失(手機、夜店)
RUN $S/listen.py check TRACK --lufs -14 --peak -1 --seconds 30 --bpm 124

在將檔案交付出去之前,check 必須通過;如果任何一項未達標,它會以狀態碼 1 退出。它也會檢測開頭是否有削波和靜音。來自模型的音樂最需要這個檢查:一個生成的底墊曾測量出 +3.2 dBTP,並包含 2,121 個被削波的樣本。使用 ffmpeg 修復(loudnorm=I=-14:TP=-1.5:LRA=11),然後再次進行 check。

交付

  • 小型副本:ffmpeg -i track.wav -c:a aac -b:a 160k track.m4a(或 -c:a libmp3lame -q:a 2)。對副本執行 check:編碼過程會移動真實峰值。
  • 用於影片配樂:使用 --seconds <影片長度> 和 --lufs -22 進行渲染,然後將其交給 video-skill,該技能會檢查最終混音。
  • 循環(Loop):使用 --bars 8,然後截掉 2.5 秒的尾部(-t <8 小節的秒數>),使其能夠乾淨地重複播放。
  • 將 score.txt 與檔案一起保存:其最後一行就是產生該檔案的精確命令。

何時不該使用這個工具

banger.py 使用振盪器和噪音來製作四拍子(four-on-the-floor)電子音樂。它沒有樣本、沒有人聲,也沒有其他類型。其混音聽起來比經過母帶處理的發行版更暗更窄(示範曲的中頻比低頻低了 17 dB)。對於原聲樂器、歌曲或指定的情緒,請使用音樂模型或版權音樂庫,然後對輸出的結果執行 look 和 check。此技能所提供的優勢是:精確的速度、調性和長度;相同種子產生完全相同結果;提供分軌、MIDI;無需授權;並且每個音符都有其理論依據。

常見錯誤

錯誤修正方法
說一首曲目「聽起來很棒」你並沒有真正聽到它。報告數字和圖表顯示的內容;讓使用者來判斷聲音好壞
為了選一個種子而渲染了 20 個groovy.py --seed N 在 0.5 秒內就能列印分數;只需渲染選中的那個
比較不同曲目的 fit 值它僅用於對一首曲目內的節奏模式進行排序
相信一個 10 秒音訊片段的調性判斷同時給出得分最高的兩個候選調性
未經 check 就交付 WAV 檔案對其執行 check,並對編碼後的副本也執行 check
直接使用模型產生的音樂而未經處理先執行 look:削波和 +dBTP 的峰值很常見
底墊音樂與人聲互相干擾使用 --lufs -22 --mute lead,並保持 1-4 kHz 頻段清晰

相關技能