0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

実機オルゴールの減衰+金属倍音+滑らか包絡

Posted at

#---------------------------------------------
# 必要ライブラリ / Import libraries
#---------------------------------------------
!pip install mido scipy -q

import mido
import numpy as np
from scipy.io.wavfile import write
from google.colab import files
from IPython.display import Audio

#---------------------------------------------
# ① MIDIファイルをアップロード / Upload MIDI file
#---------------------------------------------
print("🎵 MIDIファイルをアップロードしてください (.mid)")
uploaded = files.upload()
midi_path = list(uploaded.keys())[0]
print("✅ Uploaded:", midi_path)

#---------------------------------------------
# ② パラメータ設定 / Parameter settings
#---------------------------------------------
sr = 44100             # サンプリング周波数
volume = 0.5           # 基本音量
decay_factor = 1.8     # 減衰係数(小さいほど長い余韻)
attack_time = 0.02     # アタックの立ち上がり時間 [s]
output_wav = "/content/high_quality_musicbox.wav"

#---------------------------------------------
# ③ 改良オルゴール音合成関数 / Enhanced music-box tone
#---------------------------------------------
def smooth_envelope(t, decay_factor=1.8, attack_time=0.02):
    """滑らかな立ち上がり+指数減衰エンベロープ"""
    attack_env = np.clip(t / attack_time, 0, 1)
    decay_env = np.exp(-decay_factor * t)
    return attack_env * decay_env

def rich_musicbox_tone(freq, duration, velocity=64):
    """
    高音質オルゴール風波形を生成
    - 正弦波を中心に柔らかい倍音構成
    - 指数減衰+滑らかな立ち上がり
    - velocityで音量スケーリング
    """
    t = np.linspace(0, duration, int(sr * duration), endpoint=False)
    env = smooth_envelope(t, decay_factor, attack_time)
    amp = volume * (velocity / 127.0)

    # 基本波と倍音を柔らかく混合(オルゴールの金属音を模倣)
    wave = (
        1.0 * np.sin(2 * np.pi * freq * t)
        + 0.3 * np.sin(2 * np.pi * 2 * freq * t + np.pi / 6)
        + 0.15 * np.sin(2 * np.pi * 3 * freq * t + np.pi / 3)
        + 0.05 * np.sin(2 * np.pi * 4 * freq * t)
    )

    # 軽い非線形補正でアナログ感を加える
    wave = np.tanh(wave * 1.2)

    # エンベロープを適用
    return amp * wave * env

#---------------------------------------------
# ④ MIDI読み込み / Load MIDI
#---------------------------------------------
mid = mido.MidiFile(midi_path)
print(f"Loaded: {midi_path} | Length: {round(mid.length,2)} sec")

#---------------------------------------------
# ⑤ 音声合成 / Generate audio
#---------------------------------------------
audio = np.zeros(int(mid.length * sr) + sr, dtype=np.float32)
current_time = 0.0

for msg in mid:
    current_time += msg.time
    if msg.type == 'note_on' and msg.velocity > 0:
        freq = 440.0 * (2.0 ** ((msg.note - 69) / 12.0))
        start = int(current_time * sr)
        dur = 0.7  # 音の持続時間
        end = start + int(dur * sr)
        if end <= len(audio):
            audio[start:end] += rich_musicbox_tone(freq, dur, msg.velocity)

#---------------------------------------------
# ⑥ ポスト処理 / Post-processing
#---------------------------------------------
# 軽いローパスで高域をなめらかに
audio = np.convolve(audio, np.hanning(64)/np.sum(np.hanning(64)), mode='same')

# 正規化と保存
audio = np.clip(audio / np.max(np.abs(audio)), -1.0, 1.0)
write(output_wav, sr, (audio * 32767).astype(np.int16))
print("✅ 高音質電子オルゴール音を保存しました:", output_wav)

#---------------------------------------------
# ⑦ 再生 / Playback
#---------------------------------------------
Audio(output_wav)

🎼 改良点まとめ

改良要素 内容
エンベロープ 滑らかなアタック+自然な減衰(attack_timeexp(-decay*t)
倍音設計 1〜4倍波を柔らかくブレンド(ベル特性)
非線形補正 tanh により金属板の共鳴のような倍音の丸みを再現
ローパス処理 ハニング窓による軽い滑らか化
ベロシティ対応 強弱をMIDIのvelocityで反映
結果音色 「機械式オルゴール+トイピアノ」中間の温かみあるサウンド

💡おすすめ調整

効果 パラメータ例
音を長く伸ばす decay_factor = 1.5
音を短く切る decay_factor = 2.5
柔らかくする 倍音係数を 0.3→0.2 に変更
金属的にする 倍音係数を 0.3→0.5 に変更

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?