Pythonでギターエフェクトを学ぶ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/e4c720f9-8a48-4cf3-9f49-c26ec68e49b9.png)


EFFECTSEFFECTSさんのYouTubeチャンネル（[リンクはこちら](https://www.youtube.com/@EFFECTSEFFECTS/playlists)）では、電子回路と音響エフェクトの関係をとてもわかりやすく解説されています。この記事では、その動画を参考にしながらPythonを使って簡単なシミュレーションを行った内容をまとめます。


こちらもおすすめ
https://www.youtube.com/watch?v=OkNpiyveNiM&list=PLR6d7GGYq-3XR3_fYtXZ50MwHOW42tna4


---

##  1. 反転/非反転オペアンプによる増幅と電力計算

参考動画: [オペアンプ基本編](https://www.youtube.com/watch?v=7JKpcNQ94XI)

```python
# 入力サイン波とオペアンプ増幅のシミュレーション
```

- サンプリング周波数: 44100 Hz
- 入力信号: 1000 Hz, 振幅 0.5 V の正弦波
- ゲイン: 反転 = -10, 非反転 = +10
- 電源電圧制限: ±9V
- 負荷抵抗: 8Ω（スピーカー想定）

### 📈 結果：電圧波形と電力の比較

プロットでは、
- 灰色: 入力信号
- 破線: 反転出力
- 点線: 非反転出力

各出力についてピーク電力と平均電力も計算し、電力効率の比較が可能です。

---

##  2. ローパス・ハイパスフィルタの周波数特性（ボード線図）

参考動画: [フィルター特性の基礎](https://www.youtube.com/watch?v=ezd2s3xjeS8)

```python
# ローパス／ハイパスフィルタの周波数応答
```

- カットオフ周波数: 1000 Hz
- 周波数軸: 10 Hz ～ 100 kHz（対数スケール）

###  ポイント
- -3 dBで定義されるカットオフ周波数を明示
- ローパス: 高周波が減衰
- ハイパス: 低周波が減衰

グラフでは、各フィルタのゲイン[dB]が一目でわかり、音響回路における役割の違いが明確になります。

---

##  3. SI接頭辞と単位変換ツール

```python
# SI単位の接頭辞に対応した数値変換ツール
```

| 接頭辞 | 例 | 変換後の値 |
|--------|----|------------|
| k（キロ） | 3kΩ | 3000Ω |
| μ（マイクロ） | 100μF | 0.0001F |
| M（メガ） | 5MHz | 5,000,000Hz |
| n（ナノ） | 220nF | 2.2e-7F |
| p（ピコ） | 47pF | 4.7e-11F |

###  実用例
- 回路図の単位をプログラム上で統一したいときに便利
- 英語キーボード対応の `u` → `μ` 変換もサポート

---

##  終わりに

EFFECTSEFFECTSさんの動画は、視覚的にも音的にも学べる教材として非常に優れており、Pythonを使って自分でシミュレーションするとさらに理解が深まります。

ぜひ皆さんも、Pythonとオーディオ回路を組み合わせて、自分だけのエフェクト実験をしてみてください！

📎 関連プレイリスト：[動画一覧はこちら](https://www.youtube.com/@EFFECTSEFFECTS/playlists)

以下に、記事で紹介した3つのPythonコードを整理して掲載します。それぞれコメント付きで、日本語と英語の両方を記載しています。

---

###  1. 反転・非反転増幅器の出力波形と電力計算

```python
import numpy as np
import matplotlib.pyplot as plt

# 基本設定 / Basic parameters
fs = 44100  # サンプリング周波数 [Hz] / Sampling frequency
duration = 0.01  # 信号の持続時間 [s] / Duration of the signal
t = np.linspace(0, duration, int(fs * duration), endpoint=False)

freq = 1000  # 入力周波数 [Hz] / Input frequency
Vin_amp = 0.5  # 入力振幅 [V] / Input amplitude

# 入力サイン波生成 / Generate input sine wave
Vin = Vin_amp * np.sin(2 * np.pi * freq * t)

# ゲイン設定 / Gain settings
gain_inverting = -10          # 反転増幅器のゲイン / Gain for inverting amplifier
gain_non_inverting = 10       # 非反転増幅器のゲイン / Gain for non-inverting amplifier

# 出力電圧（クリップあり）/ Output voltage with clipping
Vout_inv = np.clip(gain_inverting * Vin, -9, 9)
Vout_noninv = np.clip(gain_non_inverting * Vin, -9, 9)

# 負荷抵抗 / Load resistance
R_load = 8  # [Ω]

# 電力計算 / Power calculation
P_in = Vin**2 / R_load
P_out_inv = Vout_inv**2 / R_load
P_out_noninv = Vout_noninv**2 / R_load

# 出力表示 / Print results
print("🔌 Power Calculation (R = 8Ω)")
print(f"Input Signal: Peak Power = {np.max(P_in):.4f} W, Avg Power = {np.mean(P_in):.4f} W")
print(f"Inverting Output: Peak Power = {np.max(P_out_inv):.4f} W, Avg Power = {np.mean(P_out_inv):.4f} W")
print(f"Non-inverting Output: Peak Power = {np.max(P_out_noninv):.4f} W, Avg Power = {np.mean(P_out_noninv):.4f} W")

# プロット / Plot
plt.figure(figsize=(12, 6))
plt.plot(t * 1000, Vin, label='Input (Vin)', color='gray')
plt.plot(t * 1000, Vout_inv, label='Inverting Output (Gain = -10)', linestyle='--')
plt.plot(t * 1000, Vout_noninv, label='Non-inverting Output (Gain = +10)', linestyle=':')
plt.title('Inverting vs Non-inverting Amplifier (Input: Sine Wave)')
plt.xlabel('Time [ms]')
plt.ylabel('Voltage [V]')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
```

---

###  2. ローパス・ハイパスフィルタの周波数特性（Bode plot）

```python
import numpy as np
import matplotlib.pyplot as plt

# カットオフ周波数 / Cutoff frequency
fc = 1000  # [Hz]

# 周波数軸の設定（対数スケール）/ Frequency range
f = np.logspace(1, 5, 1000)  # 10Hz ～ 100kHz

# ローパス / Low-pass filter
H_lpf = 1 / np.sqrt(1 + (f / fc)**2)
H_lpf_db = 20 * np.log10(H_lpf)

# ハイパス / High-pass filter
H_hpf = (f / fc) / np.sqrt(1 + (f / fc)**2)
H_hpf_db = 20 * np.log10(H_hpf)

# ボード線図プロット / Plot Bode diagram
plt.figure(figsize=(10, 6))
plt.semilogx(f, H_lpf_db, label='Low-pass Filter', linewidth=2)
plt.semilogx(f, H_hpf_db, label='High-pass Filter', linestyle='--', linewidth=2)

# カットオフと-3dBライン / Cutoff and -3dB lines
plt.axvline(fc, color='gray', linestyle=':', label=f'Cutoff Frequency = {fc} Hz')
plt.axhline(-3, color='red', linestyle=':', label='-3 dB')

plt.title('Bode Plot of Low-pass and High-pass Filters')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Gain [dB]')
plt.grid(True, which='both', linestyle=':')
plt.legend()
plt.tight_layout()
plt.show()
```

---

###  3. SI接頭辞と単位変換ツール

```python
# -*- coding: utf-8 -*-
# SI Prefix Conversion Tool

# SI接頭辞定義 / SI prefix definitions
si_prefixes = {
    'Y': 1e24, 'Z': 1e21, 'E': 1e18, 'P': 1e15, 'T': 1e12,
    'G': 1e9,  'M': 1e6,  'k': 1e3,  'h': 1e2,  'da': 1e1,
    '': 1,     'd': 1e-1, 'c': 1e-2, 'm': 1e-3, 'μ': 1e-6,
    'u': 1e-6, 'n': 1e-9, 'p': 1e-12,'f': 1e-15,'a': 1e-18,
    'z': 1e-21,'y': 1e-24
}

# 単位変換関数 / Conversion function
def convert_to_base(value, prefix):
    """
    指定された接頭辞を基準単位に変換 / Convert prefixed value to base unit
    """
    factor = si_prefixes.get(prefix)
    if factor is None:
        raise ValueError(f"Unknown prefix: {prefix}")
    return value * factor

# 使用例 / Example usage
examples = [
    (3, 'k', 'Ω'),
    (100, 'μ', 'F'),
    (5, 'M', 'Hz'),
    (220, 'n', 'F'),
    (47, 'p', 'F'),
]

# 結果表示 / Display results
print("📏 SI Prefix Conversion Examples")
for value, prefix, unit in examples:
    base_value = convert_to_base(value, prefix)
    print(f"{value}{prefix}{unit} = {base_value:.10g} {unit}")
```