code-to-music について
code-to-musicは、依頼に応じたプログラムによる作曲を支援するスキルです。電子音楽と伝統的な音楽のレンダリング手順を選び、MP3を作成する方法を案内します。
主な機能
- 01アルゴリズム作曲の手引き
- 02電子音楽と伝統音楽のパイプライン
- 03midoによるMIDI楽器設定
- 04MIDIレンダリングと音声検証
活用シーン
- 01依頼に沿った電子音楽の作曲
- 02アコースティックや管弦楽の編曲
- 03MIDI作品のMP3化
- 04MIDIや音声ファイルの確認と検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cam10001110101/ claude-skills-base --skill code-to-musicインストール後、Claude Code で/code-to-musicを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
electronic-music-pipeline.mdinstall.shrequirements.txttraditional-music-pipeline.mdscripts/__init__.pyaudio_validate.pymidi_render.pymidi_utils.py詳細
このスキルは、あらかじめ用意された解決策ではなく、音楽を作曲するためのツールとパターンを提供します。ユーザーのリクエストに基づいて動的に作曲するには、intelligence と music21 ライブラリを使用してください。
基本原則:ハードコードされたメロディーを持つ関数を呼び出すのではなく、アルゴリズムで作曲するカスタムコードを記述してください。
インストールとセットアップ
クイックインストール
自動インストーラーを実行して、完全にセットアップしてください:install.sh。すべてのシステム依存関係と Python パッケージをインストールし、インストールを検証します。
**注:**インストールスクリプトの終了時に「error: externally-managed-environment」というメッセージが表示される場合があります。これは想定内なので、安全に無視できます。依存関係はすでにインストールされています。このようなメッセージが表示された場合、インストールは成功しています。
使用可能なサウンドフォント
従来型のパイプライン(オーケストラ/アコースティック):
/usr/share/sounds/sf2/FluidR3_GM.sf2(141MB、General MIDI サウンドフォント。高品質なオーケストラ/アコースティックサンプルに使用してください)/usr/share/sounds/sf2/default.sf2(最適なものへのシンボリックリンク)- ⚠️ TimGM6mb.sf2 は使用しないでください。品質が劣り、ギターの音が電子音やピアノのようになります。
エレクトロニックパイプライン:
- 従来の音楽と同じ FluidR3_GM.sf2 サウンドフォントを使用します
- 違いは、選択する GM プログラム(オーケストラではなく、シンセプログラム 38-39、80-95)です
主な概念
- 必ずダウンロード可能な MP3 ファイルを作成してください(HTML プレーヤーではなく)
- music21.instrument クラスを便宜上使用できます:
instrument.Violin()、instrument.Violoncello()、instrument.Piano()、instrument.Trumpet()など - 重要:エクスポート後は必ず mido を使って MIDI プログラム番号を設定してください。music21 の instrument クラスは program_change メッセージを確実にはエクスポートしません。以下の mido ワークフローを参照してください。
- ノートはプログラムで生成してください。ハードコードされたシーケンスは避けてください
音楽生成パイプラインの選択
このスキルでは、異なる音楽スタイルに最適化された 2 つのレンダリングパイプラインをサポートしています。ユーザーのリクエストを注意深く読み、正しい次のファイルを読んで、適切なパイプラインを選択してください。
判断プロセス
ユーザーのリクエストから、以下を特定してください。
- ジャンルのキーワード(ハウス、テクノ、クラシック、オーケストラ、レゲエ)
- 楽器に関する言及(シンセサイザーかアコースティック楽器か)
- 音楽スタイルの説明(エレクトロニック/DJ か、従来型/アコースティックか)
- アーティストへの言及(DJ かクラシック作曲家か)
エレクトロニックパイプライン
リクエストに以下が含まれる場合は、electronic-music-pipeline.md を使用してください。
- ジャンル:ハウス、テクノ、トランス、EDM、エレクトロニックダンスミュージック、アンビエントエレクトロニック、アシッドハウス、ディープハウス、クラブミュージック、DJ セット
- 楽器:シンセサイザー、シンセベース/パッド/リード、808 ドラム、電子ドラム、スーパーソーリード、サブベース
- コンテキスト:DJ(Keinemusik、Black Coffee、Avicii、Swedish House Mafia)への言及、BPM 120-140、「クラブ向け」、「ダンス向け」
- サウンドの説明:「太いシンセサウンド」、「ブザーのようなリード」、「エレクトロニック」、「シンセを多用」
仕組み:
- リアルタイム合成を使用します(サウンドフォントは使用しません)
- DSP を使ってドラム、ベース、パッド、リードをオンザフライで合成します
- ジャンルプリセットが合成パラメーターを最適化します(deep_house、techno、trance、ambient、acid_house)
- 周波数を考慮したミキシングにより、低域/中域/高域を自動的にバランス調整します
- 最適な用途:本格的なエレクトロニックサウンド、現代的な EDM 制作
→ 詳しい手順は electronic-music-pipeline.md を参照してください
トラディショナルパイプライン
リクエストに次の内容が含まれる場合は、traditional-music-pipeline.md を使用してください。
- ジャンル:クラシック、オーケストラ、ジャズ、ブルース、ロック、カントリー、フォーク、レゲエ、スカ、交響曲、室内楽
- 楽器:バイオリン、チェロ、トランペット、フルート、ピアノ、アコースティックギター、アコースティックベース、金管アンサンブル、弦楽四重奏、オルガン(レゲエ/ゴスペル)
- コンテキスト:作曲家(モーツァルト、ベートーベン、バッハ)への言及、クラシックの時代区分(バロック、ロマン派)、「アンプラグド」、「アコースティックバージョン」
- サウンドの説明:「トラディショナル」、「アコースティック」、「オーケストラ」
仕組み:
- 録音済みのオーケストラサンプル(サウンドフォント)を使用します
- 128種類のGeneral MIDI楽器を含むFluidR3_GM.sf2サウンドフォントを使用します
- リアルなオーケストラ楽器やアコースティック楽器に適しています
- 最適な用途:クラシック、ジャズ、レゲエ、ロック、トラディショナル音楽
→ 詳しい手順は traditional-music-pipeline.md を参照してください
判断が難しい場合
- リクエストが混在している場合や、ジャンルが曖昧な場合は、デフォルトでトラディショナルを選択してください
- どちらのパイプラインも該当する可能性がある場合は、ユーザーに確認してください
重要な理由
- 誤ったパイプラインを使用すると、音質が低下します(技術的には動作しても、音がよくありません)
- 電子音楽パイプライン:リアルタイム合成により、本格的な電子音を生成します
- トラディショナルパイプライン:録音済みサンプルにより、リアルなオーケストラやアコースティックの音を生成します
利用可能なスクリプト
すべてのスクリプトは ./scripts にあります。
トラディショナル音楽のレンダリング:
midi_inventory.py- あらゆるMIDIファイルの全体構造をJSON形式で抽出しますmidi_render.py- FluidSynthを使用し、ダイナミックレンジ圧縮を適用してJSON形式の音楽構造をMP3にレンダリングしますmidi_utils.py- MIDIユーティリティ関数(ドラムの抽出、BPMの取得など)
ユーティリティ:
audio_validate.py- オーディオファイルの品質と形式を検証します
注:電子音楽もトラディショナル音楽も、同じレンダリングパイプライン(FluidSynth + FluidR3_GM.sf2)を使用します。違いは、選択するGMプログラムです。
音楽理論リファレンス
General MIDI楽器マップ全一覧(プログラム0~127)
重要:music21はprogram_changeメッセージを確実にエクスポートできません。エクスポート後は、サクソフォン、ギター、ベースなどのトラディショナル楽器であっても、必ずmidoを使ってプログラム番号を設定してください。この手順を省くと、トラックはデフォルトのピアノ(プログラム0)になります。
合成における楽器の分類: 電子音楽を作曲する際は、適切に合成するため、楽器を音響的特徴に基づいて分類してください。
- ギター(24~31):弾いたときの立ち上がりが鋭く、明るい音色で、サステインは中程度です。パッドとは異なる合成が必要です
- ベース(32~39):低周波の基音とサブベースのエネルギーを持ち、アタックは短めです
- ストリングス(40~47):持続する弓奏音、豊かな倍音、滑らかなレガートが特徴です
- ブラス(56~63):明るいアタック、持続する音色、力強い音の広がりが特徴です
- リード/木管楽器(64~79):息を含んだアタック、有機的な音色、表情豊かなダイナミクスが特徴です
- シンセリード(80~87):明るく、鋭く、アグレッシブな音で、メロディ用に設計されています
- シンセパッド(88~95):柔らかなアタック、長いサステイン、雰囲気のある音で、背景用に設計されています
- 民族楽器/打楽器(104~119):独特の音色を持つ、弾いた音または打った音です
# Piano (0-7)
0: "Acoustic Grand Piano"
1: "Bright Acoustic Piano"
2: "Electric Grand Piano"
3: "Honky-tonk Piano"
4: "Electric Piano 1"
5: "Electric Piano 2"
6: "Harpsichord"
7: "Clavinet"
# Chromatic Percussion (8-15)
8: "Celesta"
9: "Glockenspiel"
10: "Music Box"
11: "Vibraphone"
12: "Marimba"
13: "Xylophone"
14: "Tubular Bells"
15: "Dulcimer"
# Organ (16-23)
16: "Drawbar Organ"
17: "Percussive Organ"
18: "Rock Organ"
19: "Church Organ"
20: "Reed Organ"
21: "Accordion"
22: "Harmonica"
23: "Tango Accordion"
# Guitar (24-31)
24: "Acoustic Guitar (nylon)"
25: "Acoustic Guitar (steel)"
26: "Electric Guitar (jazz)"
27: "Electric Guitar (clean)"
28: "Electric Guitar (muted)"
29: "Overdriven Guitar"
30: "Distortion Guitar"
31: "Guitar Harmonics"
# Bass (32-39)
32: "Acoustic Bass"
33: "Electric Bass (finger)"
34: "Electric Bass (pick)"
35: "Fretless Bass"
36: "Slap Bass 1"
37: "Slap Bass 2"
38: "Synth Bass 1"
39: "Synth Bass 2"
# Strings (40-47)
40: "Violin"
41: "Viola"
42: "Cello"
43: "Contrabass"
44: "Tremolo Strings"
45: "Pizzicato Strings"
46: "Orchestral Harp"
47: "Timpani"
# Ensemble (48-55)
48: "String Ensemble 1"
49: "String Ensemble 2"
50: "Synth Strings 1"
51: "Synth Strings 2"
52: "Choir Aahs"
53: "Voice Oohs"
54: "Synth Voice"
55: "Orchestra Hit"
# Brass (56-63)
56: "Trumpet"
57: "Trombone"
58: "Tuba"
59: "Muted Trumpet"
60: "French Horn"
61: "Brass Section"
62: "Synth Brass 1"
63: "Synth Brass 2"
# Reed (64-71)
64: "Soprano Sax"
65: "Alto Sax"
66: "Tenor Sax"
67: "Baritone Sax"
68: "Oboe"
69: "English Horn"
70: "Bassoon"
71: "Clarinet"
# Pipe (72-79)
72: "Piccolo"
73: "Flute"
74: "Recorder"
75: "Pan Flute"
76: "Blown Bottle"
77: "Shakuhachi"
78: "Whistle"
79: "Ocarina"
# Synth Lead (80-87)
80: "Lead 1 (square)"
81: "Lead 2 (sawtooth)"
82: "Lead 3 (calliope)"
83: "Lead 4 (chiff)"
84: "Lead 5 (charang)"
85: "Lead 6 (voice)"
86: "Lead 7 (fifths)"
87: "Lead 8 (bass + lead)"
# Synth Pad (88-95)
88: "Pad 1 (new age)"
89: "Pad 2 (warm)"
90: "Pad 3 (polysynth)"
91: "Pad 4 (choir)"
92: "Pad 5 (bowed)"
93: "Pad 6 (metallic)"
94: "Pad 7 (halo)"
95: "Pad 8 (sweep)"
# Synth Effects (96-103)
96: "FX 1 (rain)"
97: "FX 2 (soundtrack)"
98: "FX 3 (crystal)"
99: "FX 4 (atmosphere)"
100: "FX 5 (brightness)"
101: "FX 6 (goblins)"
102: "FX 7 (echoes)"
103: "FX 8 (sci-fi)"
# Ethnic (104-111)
104: "Sitar"
105: "Banjo"
106: "Shamisen"
107: "Koto"
108: "Kalimba"
109: "Bag pipe"
110: "Fiddle"
111: "Shanai"
# Percussive (112-119)
112: "Tinkle Bell"
113: "Agogo"
114: "Steel Drums"
115: "Woodblock"
116: "Taiko Drum"
117: "Melodic Tom"
118: "Synth Drum"
119: "Reverse Cymbal"
# Sound Effects (120-127)
120: "Guitar Fret Noise"
121: "Breath Noise"
122: "Seashore"
123: "Bird Tweet"
124: "Telephone Ring"
125: "Helicopter"
126: "Applause"
127: "Gunshot"
ドラムマップ全一覧(MIDIチャンネル10、ノート35~81)
ドラムは音程ではなく、異なる音をノート番号で指定します。チャンネル10(0始まりの番号では9)に設定する必要があります。
# Bass Drums
35: "Acoustic Bass Drum"
36: "Bass Drum 1" # Most common kick
# Snares
38: "Acoustic Snare" # Standard snare
40: "Electric Snare"
# Toms
41: "Low Floor Tom"
43: "High Floor Tom"
45: "Low Tom"
47: "Low-Mid Tom"
48: "Hi-Mid Tom"
50: "High Tom"
# Hi-Hats
42: "Closed Hi-Hat" # Most used
44: "Pedal Hi-Hat"
46: "Open Hi-Hat"
# Cymbals
49: "Crash Cymbal 1"
51: "Ride Cymbal 1"
52: "Chinese Cymbal"
53: "Ride Bell"
55: "Splash Cymbal"
57: "Crash Cymbal 2"
59: "Ride Cymbal 2"
# Percussion
37: "Side Stick"
39: "Hand Clap"
54: "Tambourine"
56: "Cowbell"
58: "Vibraslap"
60: "Hi Bongo"
61: "Low Bongo"
62: "Mute Hi Conga"
63: "Open Hi Conga"
64: "Low Conga"
65: "High Timbale"
66: "Low Timbale"
67: "High Agogo"
68: "Low Agogo"
69: "Cabasa"
70: "Maracas"
71: "Short Whistle"
72: "Long Whistle"
73: "Short Guiro"
74: "Long Guiro"
75: "Claves"
76: "Hi Wood Block"
77: "Low Wood Block"
78: "Mute Cuica"
79: "Open Cuica"
80: "Mute Triangle"
81: "Open Triangle"
あらゆる楽器の使い方(mido ワークフロー)
重要なルール:music21 は、instrument.TenorSaxophone() や instrument.AcousticGuitar() などの楽器クラスを使っても、program_change メッセージを確実にエクスポートできません。MIDI にエクスポートした後、mido を使って必ず手動で program_change メッセージを挿入する必要があります。この手順を行わないと、すべてのトラックがピアノ(プログラム 0)の音になります。
よくある間違い:sax_part.insert(0, instrument.TenorSaxophone()) を実行すれば、トラックが自動的にサックスの音になると思い込むことです。そうはなりません。プログラム番号の設定には、引き続き mido を使う必要があります。
楽器を設定するヘルパー関数:
from mido import Message
def set_track_instrument(track, program):
"""Insert a program_change message at the beginning of a MIDI track."""
# Find position after all meta messages (track_name, etc.)
insert_pos = 0
for j, msg in enumerate(track):
if not msg.is_meta: # Insert before first non-meta message
insert_pos = j
break
else:
# If all messages are meta, insert at end
insert_pos = len(track)
track.insert(insert_pos, Message('program_change', program=program, time=0))
# Usage after loading MIDI with mido:
# set_track_instrument(mid.tracks[2], 33) # Set track 2 to Electric Bass
ステップ 1:music21 で作曲する(仮の楽器を使うか、楽器を省略する)
from music21 import stream, note, chord, tempo
score = stream.Score()
# Create parts - don't worry about instrument assignment yet
synth_lead = stream.Part()
synth_pad = stream.Part()
bass = stream.Part()
# Add your notes/chords using .insert() with explicit timing
# CRITICAL: Always use .insert(offset, note) not .append(note)
offset = 0.0
synth_lead.insert(offset, note.Note('E5', quarterLength=1.0))
offset += 1.0
synth_lead.insert(offset, note.Note('G5', quarterLength=1.0))
# ... compose your music with .insert()
score.append(synth_lead)
score.append(synth_pad)
score.append(bass)
# Export to MIDI
midi_path = # define a output path
score.write('midi', fp=midi_path)
ステップ 2:MIDI の構造を確認し、mido で楽器を割り当てる
from mido import MidiFile, Message
mid = MidiFile(midi_path)
# CRITICAL: DO NOT assume track numbers! Inspect the MIDI file first.
# Print track structure to see what tracks exist
print(f"Total tracks: {len(mid.tracks)}")
for i, track in enumerate(mid.tracks):
note_count = sum(1 for msg in track if msg.type == 'note_on' and msg.velocity > 0)
print(f"Track {i}: {note_count} notes")
# Helper function to set instruments
def set_track_instrument(track, program):
"""Insert a program_change message at the beginning of a MIDI track."""
insert_pos = 0
for j, msg in enumerate(track):
if not msg.is_meta:
insert_pos = j
break
else:
insert_pos = len(track)
track.insert(insert_pos, Message('program_change', program=program, time=0))
# Based on inspection, assign instruments to the correct tracks
# Example: if [drums, bass, guitar] were appended and inspection shows tracks 1, 2, 3 have notes:
set_track_instrument(mid.tracks[1], 80) # First part - Square Lead
set_track_instrument(mid.tracks[2], 88) # Second part - Pad
set_track_instrument(mid.tracks[3], 38) # Third part - Bass
mid.save(midi_path)
ステップ 3:ドラムの場合は、チャンネルも 9(チャンネル 10)に設定する
# If track is drums, set ALL messages to channel 9
for i, track in enumerate(mid.tracks):
if i == 1: # This is the drum track
for msg in track:
if hasattr(msg, 'channel'):
msg.channel = 9 # Channel 10 in 1-indexed
ステップ 4:オーディオにレンダリングする
from midi2audio import FluidSynth
from pydub import AudioSegment
fs = FluidSynth('/usr/share/sounds/sf2/FluidR3_GM.sf2')
wav_path = # define a path here
fs.midi_to_audio(midi_path, wav_path)
audio = AudioSegment.from_wav(wav_path)
mp3_path = # define a path here
audio.export(mp3_path, format='mp3', bitrate='192k')
よく使われるコード進行とスタイル
# Standard Progressions (Roman numerals)
"pop": ["I", "V", "vi", "IV"] # C-G-Am-F (Journey, Adele)
"epic": ["i", "VI", "III", "VII"] # Am-F-C-G (Epic trailer music)
"sad": ["i", "VI", "iv", "V"] # Am-F-Dm-E (Melancholic)
"jazz": ["ii", "V", "I", "vi"] # Dm-G-C-Am (Jazz standard)
"classical": ["I", "IV", "V", "I"] # C-F-G-C (Classical cadence)
"blues": ["I", "I", "I", "I", "IV", "IV", "I", "I", "V", "IV", "I", "I"] # 12-bar blues
"house": ["i", "VI", "III", "VII"] # Minor house progression
"reggae": ["I", "V", "vi", "IV"] # Offbeat rhythm style
"country": ["I", "IV", "V", "I"] # Simple and direct
"rock": ["I", "bVII", "IV", "I"] # Power chord style
"r&b": ["I", "V", "vi", "iii", "IV", "I", "IV", "V"] # Complex R&B
# Genre-Specific Characteristics
STYLES = {
"house": {
"bpm": 120-128,
"time_signature": "4/4",
"drum_pattern": "4-on-floor kick, offbeat hats",
"bass": "Synth bass with groove",
"common_instruments": [38, 80, 88, 4] # Synth bass, lead, pad, e-piano
},
"jazz": {
"bpm": 100-180,
"time_signature": "4/4 or 3/4",
"chords": "Extended (7th, 9th, 11th, 13th)",
"common_instruments": [0, 32, 64, 56, 73] # Piano, bass, sax, trumpet, drums
},
"orchestral": {
"bpm": 60-140,
"sections": ["strings", "woodwinds", "brass", "percussion"],
"common_instruments": [40, 41, 42, 56, 73, 47] # Violin, viola, cello, trumpet, flute, timpani
},
"rock": {
"bpm": 100-140,
"time_signature": "4/4",
"guitars": "Distorted (30) or clean (27)",
"common_instruments": [30, 33, 0, 128] # Distortion guitar, bass, piano, drums
},
"ambient": {
"bpm": 60-90,
"characteristics": "Long sustained notes, atmospheric pads",
"common_instruments": [88, 89, 90, 91, 52] # Various pads, choir
},
"trap": {
"bpm": 130-170,
"drums": "Tight snare rolls, 808 bass kicks",
"hi_hats": "Fast hi-hat patterns (1/16 or 1/32 notes)",
"common_instruments": [38, 128] # Synth bass, drums
}
}
music21 の楽器クラス
from music21 import instrument
# Strings
instrument.Violin()
instrument.Viola()
instrument.Violoncello() # Note: NOT Cello()
instrument.Contrabass()
instrument.Harp()
# Piano
instrument.Piano()
instrument.Harpsichord()
# Brass
instrument.Trumpet()
instrument.Trombone()
instrument.Tuba()
instrument.Horn() # French horn
# Woodwinds
instrument.Flute()
instrument.Clarinet()
instrument.Oboe()
instrument.Bassoon()
instrument.SopranoSaxophone()
instrument.AltoSaxophone()
instrument.TenorSaxophone() # Most common for jazz
instrument.BaritoneSaxophone()
# Other
instrument.AcousticGuitar()
instrument.ElectricGuitar()
instrument.Bass()
instrument.Timpani()
# CRITICAL: music21 has LIMITED support for electronic instruments and drums
# For synths, drums, and electronic sounds, the following steps must be taken:
# 1. Create a Part without an instrument (or use a placeholder like Piano())
# 2. Use mido library to INSERT program_change messages after export
# 3. Set drums to MIDI channel 10 (channel 9 in 0-indexed) or they won't sound like drums
#
# Common mistakes:
# - instrument.Cello() doesn't exist - use Violoncello()
# - instrument.FrenchHorn() doesn't exist - use Horn()
# - Setting part.partName doesn't change the sound - MIDI program must be set with mido
# - Drums on channel 0 will play as pitched notes, not drum sounds
音符の長さ(4 分音符 = 1.0)
- 全音符:4.0
- 2 分音符:2.0
- 4 分音符:1.0
- 8 分音符:0.5
- 16 分音符:0.25
- 付点 4 分音符:1.5
- 3 連 4 分音符:0.667
mido クイックリファレンス
電子音楽やドラムでは、music21 でエクスポートした後、mido を使って MIDI プログラムを設定します。
from mido import MidiFile, Message
mid = MidiFile(midi_path)
# Define helper function
def set_track_instrument(track, program):
"""Insert a program_change message at the beginning of a MIDI track."""
insert_pos = 0
for j, msg in enumerate(track):
if not msg.is_meta:
insert_pos = j
break
else:
insert_pos = len(track)
track.insert(insert_pos, Message('program_change', program=program, time=0))
# Insert program_change messages
for i, track in enumerate(mid.tracks):
if i == 1: # Your track (tracks start at 1, not 0)
set_track_instrument(track, 38) # Synth Bass 1
# For drums: Set channel to 9 (channel 10 in 1-indexed)
for i, track in enumerate(mid.tracks):
if i == 1: # Drum track
for msg in track:
if hasattr(msg, 'channel'):
msg.channel = 9
mid.save(midi_path)
よく使われる MIDI プログラム:
- 38:シンセベース 1
- 80:スクエアリード
- 81:ノコギリ波リード
- 88:パッド 1(ニューエイジ)
- 25:アコースティックギター(スチール弦)— 音量が大きく、音が埋もれにくい
- 33:アコースティックベース
よく使われるテクニック
ドラムのプログラミング(4 つ打ちハウスビート)
重要:music21 の .append() は、音符を同時ではなく、連続して追加します。キック、スネア、ハイハットを同時に鳴らすレイヤー構成のドラムでは、明示的なタイミングを指定して .insert(offset, note) を使う必要があります。
パートに音符を追加する際は、必ず .insert() を使ってください:
ほとんどの優れた作曲ではレイヤー構成が必要になるため、ドラム、ベース、ギター、パッドなど、すべてのトラックで 必ず part.insert(offset, note) を使ってください。これによりタイミングの不具合を防ぎ、適切な同期を保てます。
パートに音符を追加する際、.insert() と .append() を混在させないでください。ドラムに .insert() を使い、ほかの楽器に .append() を使うと、music21 がトラックの長さを誤って計算し、意図した長さの 5~10 倍(1.5 分ではなく 8 分)になることがあります。その場合、実際に音が鳴るのは最初の 20~25%だけです。
注:パートを Score に追加するために score.append(part) を使うのは問題ありません。問題となるのは、音符やコードをパートに追加することであり、パートを Score に追加することではありません。
正しいパターン:
# RIGHT: Use .insert() for notes, .append() for parts
drum_part = stream.Part()
bass_part = stream.Part()
offset = 0.0
for beat in range(16):
# Kick and hi-hat on same beat (layered)
drum_part.insert(offset, note.Note(36, quarterLength=0.5)) # Kick
drum_part.insert(offset, note.Note(42, quarterLength=0.5)) # Hi-hat
# Bass note
bass_part.insert(offset, note.Note('A2', quarterLength=0.5))
offset += 0.5 # Advance time
# Add parts to score (this .append() is fine)
score.append(drum_part)
score.append(bass_part)
小節全体を音で埋める
重要:ループを使って作曲する場合は、各小節に隙間ができないよう、音符で小節を完全に埋めてください。よくある間違いは、小節全体の長さに満たない音符を配置し、無音の隙間を残すことです。
問題のあるパターン(隙間ができます):
bar_length = 1.5 # 6/8 time signature
offset = 0.0
for bar in range(8):
# Only fills first 1.0 quarter lengths, leaving 0.5 silent!
guitar_part.insert(offset, note.Note('D3', quarterLength=0.5))
guitar_part.insert(offset + 0.5, chord.Chord(['D3', 'F#3', 'A3'], quarterLength=0.5))
# Missing: offset + 1.0 to offset + 1.5
offset += bar_length # Advances to next bar, but gap remains
# Result: Guitar plays for 10 seconds, then silence for remaining duration
解決パターン(小節全体を埋めます):
bar_length = 1.5 # 6/8 time signature
offset = 0.0
for bar in range(8):
# Fill the ENTIRE bar with notes
guitar_part.insert(offset, note.Note('D3', quarterLength=0.5)) # 0.0 to 0.5
guitar_part.insert(offset + 0.5, chord.Chord(['D3', 'F#3', 'A3'], quarterLength=0.5)) # 0.5 to 1.0
guitar_part.insert(offset + 1.0, note.Note('D3', quarterLength=0.5)) # 1.0 to 1.5 ✓ Complete!
offset += bar_length
# Result: Guitar plays continuously throughout the entire piece
ベストプラクティス:offset += bar_length に進む前に、最後の音符が offset + bar_length ちょうどで終わることを確認してください。たとえば:
bar_length = 1.5の場合、最後の音符はoffset + 1.0から始まり、quarterLength=0.5としてoffset + 1.5まで続くようにしますbar_length = 2.0の場合、最後の音符はoffset + 1.5から始まり、quarterLength=0.5としてoffset + 2.0まで続くようにします
ベストプラクティス
作曲の品質
- 変化をつける:曲全体で同じ 4 小節を繰り返さないでください
- 音楽理論を活用する:実際のコード進行を使い、適切な声部進行にします
- 楽器の音域を守る:バイオリン(G3~E7)、チェロ(C2~C6)、トランペット(E3~C6)
- 強弱を加える:p、mp、mf、f、ff の記号やクレッシェンドを使います
- 構成を整える:イントロ → 展開 → クライマックス → 解決
- 人間らしさを加える:タイミングやベロシティに変化をつけ、機械的な音を避けます
import random n = note.Note('C5', quarterLength=1.0 + random.uniform(-0.05, 0.05)) n.volume.velocity = 80 + random.randint(-5, 5)
技術的な品質
- SoundFont:最高の品質を得るには FluidR3_GM.sf2 を使用します
- ビットレート:最低 192kbps、高品質にするには 320kbps
- リミッティング:クリッピングを防ぐため、
audio.compress_dynamic_range()を適用します - タイミングの精度:quarterLength の値は慎重に設定します
- クリーンアップ:MP3 への変換後、一時的な MIDI/WAV ファイルを削除します
よくある落とし穴
- 重大:トラック番号を決めつけないでください - MIDI ファイルを note counts で最初に調べ、各トラックがどの楽器かを確認せずに、ギターに対して
if i == 3を使わないでください - 重大:パートにノートを追加するには、必ず part.insert(offset, note) を使用してください -
part.append(note)を使ったり、.insert()と.append()を混在させたりしないでください。これにより、トラックの長さが意図したものの 5~10 倍になり、そのうち音が鳴るのは 20~25%だけというタイミングの不具合が発生します。詳しくは「ドラムのプログラミング」セクションをご覧ください - 重大:program_change メッセージを挿入してください -
msg.program = Xではなく、track.insert(pos, Message('program_change', ...))を使用してください。mido クイックリファレンスをご覧ください - 重大:ベロシティを設定してください - リードは 90~105、バックグラウンドは 50~65 です。「ミキシングとバランス」セクションをご覧ください
- 重大:ベースのオクターブ - A1~A2(55~110 Hz)を使用し、ほとんどのシステムで聞こえない A0~G0 は使用しないでください
instrument.Cello()は存在しません -Violoncello()を使用してください- テンポの設定忘れ - 最初のパートに
tempo.MetronomeMark()を追加してください - ドラムの音にならない - mido でチャンネルを 9 に設定してください(mido クイックリファレンスをご覧ください)
ミキシングとバランス
重大:MIDI プログラム番号を設定するだけでは不十分です。ベロシティを明示的に制御しないと、一部の楽器はまったく聞こえなくなることがあります。
ベロシティの設定
music21 はすべてのノートにデフォルトのベロシティ 64 を使用するため、適切にミキシングできません。MIDI のエクスポート後に mido を使ってベロシティを設定します:
from mido import MidiFile
def set_track_velocity(track, velocity):
"""Set velocity for all note_on messages in a track."""
for msg in track:
if msg.type == 'note_on' and msg.velocity > 0:
msg.velocity = velocity
mid = MidiFile(midi_path)
for i, track in enumerate(mid.tracks):
if i == 1: # Drums
set_track_velocity(track, 75)
elif i == 2: # Bass
set_track_velocity(track, 80)
elif i == 3: # Lead instrument (sax, guitar, trumpet)
set_track_velocity(track, 95)
elif i == 4: # Background (organ, pads)
set_track_velocity(track, 55)
mid.save(midi_path)
ベロシティのガイドライン
役割別:
- リード楽器(メロディー、ソロ):90~105
- リズム楽器(ギターのスカンク、コード伴奏):85~100
- ベース:75~85
- ドラム:70~90
- バックグラウンド(パッド、オルガン):50~65
周波数帯域別:
- 低域(20~250 Hz):ベース、キック - 75~85 で支配的な音は 1 つだけにします
- 中域(250~2000 Hz):最も音が混み合う帯域です - ベロシティを使って分離します(リードは 90 以上、バックグラウンドは 50~65)
- 高域(2000 Hz 以上):ハイハット、シンバル - 耳障りにならず明瞭になるよう、70~85 にします
Soundfont の音量レベルに関する問題
FluidR3_GM の楽器は録音レベルがそれぞれ異なります。ベロシティが正しくても、聞こえない楽器がある場合があります:
音量の小さいプログラム(リード/リズムには使用しないでください):
- プログラム 27(エレキギター - クリーン) - 非常に音量が小さい
- プログラム 24(アコースティックギター - ナイロン)
- プログラム 73(フルート)
より良い代替候補:
- プログラム 25(アコースティックギター - スチール) - 8~10dB 音量が大きく、音が埋もれません
- プログラム 28(エレキギター - ミュート) - パーカッシブな音色です
- プログラム 30(ディストーションギター) - アグレッシブな音色です
追加の対処方法:
- ノートの長さを伸ばします(0.25 ではなく、quarterLength を最低 0.4 にします)
- オクターブを分けます(競合する楽器を異なるオクターブに移動します)
- ベロシティに大きな差をつけます(音量の小さい楽器を 110、大きい楽器を 40 にします)
ミキシングのチェックリスト
レンダリング前に確認します:
- ✅ リードのベロシティが 90~105
- ✅ バックグラウンドのベロシティが 50~65
- ✅ ベースのベロシティが 75~85
- ✅ 音量の小さい楽器(プログラム 24、27、73)がないか確認し、代替候補を使用
- ✅ リズム楽器の quarterLength が最低 0.4
リソース
- music21 ドキュメント:https://web.mit.edu/music21/doc/
- General MIDI 仕様:https://www.midi.org/specifications-old/item/gm-level-1-sound-set
- 音楽理論:https://www.musictheory.net/
- IMSLP(無料楽譜):https://imslp.org/ - ここからクラシックの MIDI をダウンロードできます!
制限事項
- インストゥルメンタルのみ - 歌詞やボーカルはありません
- MIDI ベースの合成 - スタジオ品質の録音ではありません
- リアルタイム再生には非対応 - 再生前にファイルをレンダリングする必要があります