Community生产力与协作github.com

音乐技能

在终端中制作、检查和理解音乐,专为无法听到音乐的AI智能体设计。当用户需要制作音乐(如浩室或科技电子舞曲、节拍、循环、视频或语音背景音乐、指定长度、速度或调性的音乐、分轨或MIDI),或者需要了解音频内容(如“BPM是多少”、“这是什么调性”、“高潮在哪里”、“为什么混音听起来浑浊”),或者在发布前检查音频(响度LUFS、真实峰值、削波、单声道兼容性)时使用。也适用于分析乐句为何好听(切分、摇摆、微时值、声部进行、段落划分与高潮),以及检查生成式音乐模型输出的内容。

音乐技能 是什么?

music-skill 是一个终端工具集,专为无法直接听到音频的AI智能体设计,使其能够制作、分析和交付电子音乐。它由两个核心脚本组成:`banger.py` 用于根据种子、风格、速度、调性和长度等参数快速生成四拍子电子舞曲(如浩室或电子乐);`listen.py` 用于分析任何音频文件(包括生成式模型输出的音频),提取关键信息,如BPM、调性、响度(LUFS)、真实峰值、音色平衡、立体声宽度,并生成可视化的时间线图和频谱图。该技能基于规则而非机器学习,通过“Banger Lab”方法对每种乐器(如底鼓、军鼓、镲片、贝斯、和弦、主音)进行搜索优化,确保节拍稳固且具备中等程度的切分感与变化。它还提供“检查”功能,确保输出文件符合指定的响度和峰值目标,并检测潜在的削波或静音问题。该技能适用于Claude Code等终端环境,需要 uv 和 ffmpeg 依赖,并明确指出了其局限性:仅支持四拍子电子乐,不支持采样、人声或其他流派。

兼容平台✓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 的新对话。

文档

音乐技能 是做什么的?

脚本位于此文件旁的 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秒结束,让混响按时淡出
语音背景音乐--lufs -22 --mute lead (也可以尝试静音 clap)
用于DAW或混音检查的分轨--stems 会写入 stems/<layer>.wav;track.mid 始终写入

小节数决定曲式结构:8-10小节是循环;12-22小节是前奏、高潮、尾奏;24-46小节在两个高潮之间加入一个桥段落和一个蓄势段落;48小节及以上是完整形式,包含一个律动段落和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 是强奏。贝斯:R 根音,5 五音,O 八度音,3 三音。主音:两个小节范围内的音阶度数0-9。fit 表示该部分满足其规则的切合度;weakest 列出了它未满足的规则名称。

要选择种子,先以文本形式试听:python3 $S/groove.py --seed N 仅运行搜索(0.5秒,无音频,无依赖)。尝试几个种子,阅读和弦与主音,然后渲染你最终选定的那个。你无法判断“听起来好不好听”:请如实说明,并将文件交给用户。

曲目的生成方式

该方法来源于 Banger Lab。它是一种搜索算法,而非模型,每条规则都源自对节奏或音高感知的研究。

  1. 滚动生成。 种子选择风格、速度、调性、音阶和目标:每小节镲片数、切分程度、和弦数量。
  2. 猜测。 每种乐器以随机16步节奏型开始。
  3. 测试。 每一个单步变化(添加、移除、滑动、变响、变弱)都根据该乐器的规则进行评分,同时测试少量随机两步跳跃。保留最佳者。
  4. 锁定。 当没有任何变化能获得更高分数时,该部分完成,并在其上编写下一个乐器。顺序:底鼓、军鼓、镲片、开镲、打击乐、贝斯、和弦、主音。每一层都有四次随机初始值,并保留最佳结果。
  5. 聆听。 banger.py 单独渲染每种乐器,测量其能量在六个频段中的分布,然后进行第二轮调整,调整镲片、打击乐、贝斯、和弦和主音,以避免不同乐器在同一时间步上占据相同频段。
  6. 编曲。 这些部分被组织成段落,在每4小节和8小节的结尾有填充,在桥段落中打开低通滤波器,在蓄势段落中加入军鼓滚奏和提升器,一拍休止,然后进入高潮。

律动的源泉:规则

当你以任何方式编写或编辑音乐时(手工编写节奏型、MIDI,或为音乐模型编写提示词),请使用这些规则。score.json 中包含曲目中每条规则的评分和来源。

部分规则来源
底鼓每拍都有;最多0-2个额外底鼓,放置于拍前;从不连续两下Butler 2006
军鼓在第二拍和第四拍演奏强音,避开第一拍和第三拍;额外的军鼓是弱音,在弱十六分音符上Butler 2006; Witek 2014
镲片在弱拍上,即底鼓之间;均匀分布;在小节两个半部分中保持一致;强弱交替Butler 2006; Toussaint 2005
开镲位于两个底鼓中间,绝不在底鼓或军鼓上Butler 2006
打击乐均匀分布,在底鼓和军鼓休止的位置,包含25-50%的弱幽灵音Toussaint 2005; Witek 2014
贝斯在底鼓不演奏的地方演奏;60-90%的时间演奏根音(或其八度音),使用五音或三音增添色彩Plomp & Levelt 1965; Krumhansl & Kessler 1982
和弦第一小节是主和弦;根音按级进、三度或四度进行;每个声部以最短路径移动到下一个和弦Krumhansl & Kessler 1982; Tymoczko 2011
主音在强拍上演奏和弦音;绝不在和弦音之上小二度;小步进行;第一小节提出疑问(结束在非主音上),第二小节以相似节奏回答(结束在主音上);在和弦发音的间隙中演奏Plomp & Levelt 1965; Huron 2001; Caplin 1998
所有部分中等切分:一些音符位于弱拍上,并跳过强拍。切分过少则死板,过多则失去节拍感Witek et al. 2014
时值每种乐器的摇摆和推/拉 保持在12毫秒以下(镲片延迟,军鼓提前)。较大的偏移会降低律动评分Davies et al. 2013
混音同一时间步上两个部分占据同一频段会互相模糊;同一时间步上不超过4个部分同时演奏Plomp & Levelt 1965
曲式桥段落、蓄势段落和高潮:移除底鼓和贝斯,增加紧张感,再将其带回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

从时间线上解读结构。次低频和低频下降20-30dB是桥段落(底鼓和贝斯已移出)。高频和极高频上升而次低频保持静默是蓄势段落。所有频段同时恢复是高潮。然后查看图片(波形图、频谱图、六个频段轨道、响度曲线):一个提升器表现为一条对角线,一个底鼓表现为底部一列明亮的点,一大块无缝的彩色块是缺乏动态变化的混音。在描述某个时刻时,请使用图片坐标轴上的时间。

其可信度,基于24首已知答案的曲目测试:

  • 速度:24首中24首误差在0.2 BPM以内。它倾向于70-190 BPM,因此其他素材上可能出现减半或加倍的速度。强度低于2表示没有稳定节拍:请说明BPM是猜测值。
  • 调性:24首中19首主音正确,在短或稀疏的音频上可靠性较低。大调与小调的判断较弱,且无法区分调式。当前两个候选分数接近时会给出提示;请报告两者。
  • 响度和真实峰值:与 ffmpeg -af ebur128=peak=true 的结果一致,误差在0.1以内。

分轨对比: mix

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

每个分轨:响度及其能量所在频段。接着是最互相掩盖的配对(相同频段、相同时间点),以及相对于最响分轨非常安静的分轨。一对的掩盖度超过60%意味着两个部分在同一个空间中争夺:需要在时值、音高或电平上移动其中一个。

需要达成的目标数值与检查

目标数值
独立曲目(流媒体平台会标准化到附近数值)-14 LUFS 集成值
网络视频或播客的最终混音-16 LUFS
语音背景音乐大约 -22 LUFS
真实峰值,始终-1 dBTP或以下:有损编码会超过该值
峰值-响度比低于7 dB过度压缩:声音扁平且令人疲劳
120 Hz以下的立体声相关性低于0.6低频可能在单声道中消失(手机、俱乐部)
RUN $S/listen.py check TRACK --lufs -14 --peak -1 --seconds 30 --bpm 124

在交付文件之前,check 必须通过;如果未通过则退出并返回1。它还会检查开头的削波和静音。来自模型的音乐最需要此项检查:一个生成的背景音乐实测峰值达到+3.2 dBTP,并包含2121个削波采样。使用 ffmpeg 修复(loudnorm=I=-14:TP=-1.5:LRA=11),然后再次检查。

交付

  • 小尺寸副本:ffmpeg -i track.wav -c:a aac -b:a 160k track.m4a(或 -c:a libmp3lame -q:a 2)。在副本上运行 check:编码会改变真实峰值。
  • 用于影片:使用 --seconds <电影长度> 和 --lufs -22 渲染,然后交给 video-skill,它会检查最终混音。
  • 循环:使用 --bars 8,然后剪掉2.5秒的尾部(-t <8小节的秒数>),以便干净地重复。
  • 将 score.txt 与文件一起保存:其最后一行是生成它的确切命令。

何时不应使用此工具

banger.py 使用振荡器和噪声制作四拍子电子音乐。它没有采样、没有人声,也没有其他流派,其混音比母带发行的作品更暗、更窄(演示版的中频比低频低17 dB)。对于原声乐器、歌曲或有明确情绪需求,请使用音乐模型或音库曲目,然后对结果运行 look 和 check。此工具提供的则是:精确的速度、调性和长度,相同种子产生相同结果,分轨、MIDI,无需授权,以及每个音符背后的原因。

常见错误

错误修正
说一首曲目“听起来很棒”你没有听到它。报告数值和图片显示的内容;由用户判断声音
渲染20个种子来选择一个groove.py --seed N 在0.5秒内打印评分;渲染你选定的那个
跨曲目比较 fit它只在一首曲目内部对节奏型进行排名
在10秒的片段上轻信调性判断给出两个最优候选
未经 check 就交付WAV文件要 check 它,并且也要检查编码后的副本
直接使用来自模型的音乐先 look:削波和+dBTP峰值很常见
背景音乐与人声冲突使用 --lufs -22 --mute lead,并保持1-4 kHz清晰

相关技能