# ノートパソコン向け .m4aから楽譜(PDF)変換アプリ
以下は、通常のノートパソコンで動作する、.m4aオーディオファイルを楽譜(PDF)に変換する完全なPythonアプリケーションのコードです。この実装では、より精度の高い変換を実現するために追加のライブラリを使用しています。
## 必要なライブラリのインストール
まず、以下のコマンドで必要なライブラリをインストールしてください:
```bash
pip install librosa numpy matplotlib pretty_midi music21 pydub musescore
```
また、楽譜生成のために [MuseScore](https://musescore.org/) をインストールする必要があります。
## 完全なソースコード
```python
import os
import numpy as np
import librosa
import librosa.display
import matplotlib.pyplot as plt
from pydub import AudioSegment
from pretty_midi import PrettyMIDI, Instrument
from music21 import converter, environment, stream, note, chord, tempo, meter
import subprocess
from pathlib import Path
class AudioToSheetMusicConverter:
def __init__(self):
# MuseScoreのパスを設定(環境に合わせて変更)
self.setup_musescore_path()
def setup_musescore_path(self):
"""MuseScoreのパスを自動検出または設定"""
env = environment.Environment()
# Windows
if os.name == 'nt':
ms_path = "C:/Program Files/MuseScore 4/bin/MuseScore4.exe"
# macOS
elif os.name == 'posix' and 'darwin' in os.uname().sysname.lower():
ms_path = "/Applications/MuseScore 4.app/Contents/MacOS/mscore"
# Linux
else:
ms_path = "/usr/bin/musescore"
if Path(ms_path).exists():
env['musescoreDirectPNGPath'] = ms_path
env['musicxmlPath'] = ms_path
else:
print(f"MuseScoreが見つかりませんでした: {ms_path}")
print("MuseScore 4をインストールしてください: https://musescore.org/")
def convert_m4a_to_wav(self, m4a_path, wav_path):
"""m4aファイルをwavに変換"""
try:
audio = AudioSegment.from_file(m4a_path, format="m4a")
audio.export(wav_path, format="wav")
return True
except Exception as e:
print(f"音声ファイル変換エラー: {e}")
return False
def analyze_audio(self, audio_path):
"""オーディオファイルを分析して特徴を抽出"""
y, sr = librosa.load(audio_path, sr=44100)
# 基本特徴量
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
chroma = librosa.feature.chroma_cqt(y=y, sr=sr)
pitches, magnitudes = librosa.piptrack(y=y, sr=sr)
return {
'waveform': y,
'sample_rate': sr,
'tempo': tempo,
'beat_frames': beat_frames,
'chroma': chroma,
'pitches': pitches,
'magnitudes': magnitudes
}
def create_midi(self, analysis_result, midi_path):
"""分析結果からMIDIファイルを生成"""
midi = PrettyMIDI()
piano = Instrument(program=0) # ピアノ
# テンポ設定
midi_tempo = int(analysis_result['tempo'])
# ビート情報を取得
beat_times = librosa.frames_to_time(analysis_result['beat_frames'],
sr=analysis_result['sample_rate'])
# ピッチ情報からノートを生成
pitches = analysis_result['pitches']
magnitudes = analysis_result['magnitudes']
for t in range(pitches.shape[1]):
# 最も強いピッチを選択
index = magnitudes[:, t].argmax()
pitch = pitches[index, t]
if pitch > 0:
note_num = int(round(librosa.hz_to_midi(pitch)))
velocity = int(np.interp(magnitudes[index, t],
[magnitudes.min(), magnitudes.max()],
[60, 127]))
# ノートの開始と終了時間(簡易的にビートを使用)
start = beat_times[t % len(beat_times)] if len(beat_times) > 0 else t * 0.5
end = start + 0.5 # 固定の音価
midi_note = PrettyMIDI.Note(
velocity=velocity,
pitch=note_num,
start=start,
end=end
)
piano.notes.append(midi_note)
midi.instruments.append(piano)
midi.write(midi_path)
return midi_path
def midi_to_sheet_music(self, midi_path, output_path):
"""MIDIファイルを楽譜(PDF)に変換"""
try:
# music21でMIDIを読み込み
score = converter.parse(midi_path)
# 基本的な楽譜設定
score.insert(0, meter.TimeSignature('4/4'))
score.insert(0, tempo.MetronomeMark(number=120))
# PDFに出力
score.write('musicxml.pdf', fp=output_path)
return True
except Exception as e:
print(f"楽譜生成エラー: {e}")
return False
def visualize_analysis(self, analysis_result, image_path):
"""分析結果を可視化して画像として保存"""
plt.figure(figsize=(14, 10))
# 波形表示
plt.subplot(3, 1, 1)
librosa.display.waveshow(analysis_result['waveform'],
sr=analysis_result['sample_rate'])
plt.title('Waveform')
# クロマグラム
plt.subplot(3, 1, 2)
librosa.display.specshow(analysis_result['chroma'],
y_axis='chroma',
x_axis='time')
plt.colorbar()
plt.title('Chromagram')
# スペクトログラム
plt.subplot(3, 1, 3)
D = librosa.amplitude_to_db(
np.abs(librosa.stft(analysis_result['waveform'])),
ref=np.max
)
librosa.display.specshow(D,
y_axis='log',
x_axis='time',
sr=analysis_result['sample_rate'])
plt.colorbar(format='%+2.0f dB')
plt.title('Spectrogram')
plt.tight_layout()
plt.savefig(image_path)
plt.close()
return image_path
def process_audio(self, input_path, output_dir):
"""メイン処理: m4a → WAV → 分析 → MIDI → 楽譜PDF"""
# 出力ディレクトリ作成
os.makedirs(output_dir, exist_ok=True)
# ファイルパス設定
input_m4a = Path(input_path)
temp_wav = Path(output_dir) / "temp_audio.wav"
temp_midi = Path(output_dir) / "temp_music.mid"
output_pdf = Path(output_dir) / f"{input_m4a.stem}_sheet_music.pdf"
output_image = Path(output_dir) / f"{input_m4a.stem}_analysis.png"
print(f"処理を開始: {input_m4a.name}")
# 1. m4a → wav変換
print("音声ファイルを変換中...")
if not self.convert_m4a_to_wav(input_m4a, temp_wav):
return False
# 2. 音声分析
print("音声を分析中...")
analysis = self.analyze_audio(temp_wav)
# 3. 分析結果を可視化
print("分析結果を可視化中...")
self.visualize_analysis(analysis, output_image)
print(f"分析画像を保存: {output_image}")
# 4. MIDI生成
print("MIDIを生成中...")
self.create_midi(analysis, temp_midi)
# 5. 楽譜PDF生成
print("楽譜を生成中...")
if self.midi_to_sheet_music(temp_midi, output_pdf):
print(f"楽譜PDFを生成: {output_pdf}")
return True
else:
print("PDF生成に失敗しました")
return False
def main():
print("=== m4aから楽譜PDF変換ツール ===")
# 入力ファイルと出力ディレクトリを指定
input_file = input("処理するm4aファイルのパスを入力: ").strip('"')
output_dir = input("出力ディレクトリを入力(デフォルトはoutput): ").strip('"') or "output"
converter = AudioToSheetMusicConverter()
if Path(input_file).exists():
if converter.process_audio(input_file, output_dir):
print("処理が正常に完了しました!")
else:
print("処理中にエラーが発生しました")
else:
print("入力ファイルが見つかりません")
if __name__ == "__main__":
main()
```
## 機能説明
1. **m4aからWAV変換**:
- `pydub`ライブラリを使用して高品質な変換を実現
2. **高度な音声分析**:
- テンポ検出
- ビートトラッキング
- ピッチ検出
- クロマ特徴量分析
3. **MIDI生成**:
- 検出したピッチとリズム情報からMIDIファイルを生成
- ベロシティ(音の強さ)も考慮
4. **楽譜生成**:
- MuseScoreを使用して高品質なPDFを出力
- 拍子記号やテンポ表示も含む
5. **分析可視化**:
- 波形表示
- クロマグラム
- スペクトログラム
## 使用方法
1. 上記のコードを`audio_to_sheet.py`として保存
2. 必要なライブラリをインストール
3. MuseScore 4をインストール
4. コマンドラインでスクリプトを実行:
```bash
python audio_to_sheet.py
```
5. プロンプトに従ってm4aファイルのパスを入力
## 注意点
- 複雑な音楽(和音が多い曲など)の変換精度には限界があります
- 最適な結果を得るためには、単旋律の楽器演奏(ピアノ、バイオリンなど)が適しています
- 処理時間は音源の長さによって異なります(1分の音声で約10-30秒程度)
## さらに改善するには
1. より高度なピッチ検出アルゴリズムの実装
2. 和音検出機能の追加
3. ユーザーが編集可能な中間形式(MusicXMLなど)の出力
4. GUIアプリケーションとしてのパッケージ化(PyQtなどで)
このコードは、個人使用に適した基本機能を備えています。より専門的な用途には、商用の音声→楽譜変換ソフトウェアの使用も検討してください。