mcpField
C
code-to-music

code-to-music

github.com/cam10001110101クリエイティブ・メディア844 回インストール26 週間前に更新
リポジトリ

code-to-music について

code-to-musicは、依頼に応じたプログラムによる作曲を支援するスキルです。電子音楽と伝統的な音楽のレンダリング手順を選び、MP3を作成する方法を案内します。

主な機能

  1. 01アルゴリズム作曲の手引き
  2. 02電子音楽と伝統音楽のパイプライン
  3. 03midoによるMIDI楽器設定
  4. 04MIDIレンダリングと音声検証

活用シーン

  1. 01依頼に沿った電子音楽の作曲
  2. 02アコースティックや管弦楽の編曲
  3. 03MIDI作品のMP3化
  4. 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.md
install.sh
requirements.txt
traditional-music-pipeline.md
scripts/
__init__.py
audio_validate.py
midi_render.py
midi_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

リソース

制限事項

  • インストゥルメンタルのみ - 歌詞やボーカルはありません
  • MIDI ベースの合成 - スタジオ品質の録音ではありません
  • リアルタイム再生には非対応 - 再生前にファイルをレンダリングする必要があります

コメント