音の合成と数学：和積・積和・倍角公式をPythonで学ぶ

# はじめに
本記事では、音の合成に関連する数学的な公式を使い、Pythonコードでその実装を行います。具体的には、基本的な正弦波の加算や乗算をはじめ、和積・積和変換、倍角公式、さらには加法定理に至るまで、音波を数式で操作する方法について解説します。

## Pythonコード

```python
#  ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Audio, display

#  サンプリング設定
fs = 44100  # サンプリング周波数（44.1kHz）
duration = 2.0  # 音の長さ（秒）
t = np.linspace(0, duration, int(fs * duration), endpoint=False)  # 時間軸

#  周波数設定：ドとレ
f_do = 261.63  # ドの周波数（Hz）
f_re = 293.66  # レの周波数（Hz）
omega1 = 2 * np.pi * f_do  # ドの角周波数（rad/s）
omega2 = 2 * np.pi * f_re  # レの角周波数（rad/s）

#  基本波形
sin1 = np.sin(omega1 * t)  # sin(ω₁t) [ド]
sin2 = np.sin(omega2 * t)  # sin(ω₂t) [レ]
sum_sin = sin1 + sin2  # sin(ω₁t) + sin(ω₂t) [和音]
prod_sin = sin1 * sin2  # sin(ω₁t) × sin(ω₂t) [積]

#  和積公式
sum_to_prod = 2 * np.sin((omega1 + omega2) / 2 * t) * np.cos((omega1 - omega2) / 2 * t)  # 和積公式

#  積和公式
prod_to_sum = 0.5 * (np.cos((omega1 - omega2) * t) - np.cos((omega1 + omega2) * t))  # 積和公式

#  倍角の公式（Double Angle）
double_sin = 2 * sin1 * np.cos(omega1 * t)  # sin(2ω₁t)
double_cos = 2 * np.cos(omega1 * t) ** 2 - 1  # cos(2ω₁t)

#  加法定理（Addition Formulas）
sin_add = np.sin(omega1 * t) * np.cos(omega2 * t) + np.cos(omega1 * t) * np.sin(omega2 * t)  # sin(ω₁t + ω₂t)
cos_add = np.cos(omega1 * t) * np.cos(omega2 * t) - np.sin(omega1 * t) * np.sin(omega2 * t)  # cos(ω₁t + ω₂t)

# 🔊 正規化
normalize = lambda x: x / np.max(np.abs(x))  # 音声を-1から1の範囲に正規化

# 📈 波形プロット（6段構成）
plt.figure(figsize=(14, 14))

# 1. sin(ω₁t), sin(ω₂t)
plt.subplot(6, 1, 1)
plt.plot(t[:1000], sin1[:1000], label='sin(ω₁t) [Do]', alpha=0.7)
plt.plot(t[:1000], sin2[:1000], label='sin(ω₂t) [Re]', alpha=0.7)
plt.title('Basic Sine Waves')
plt.legend(), plt.grid()

# 2. sin(ω₁t) + sin(ω₂t)
plt.subplot(6, 1, 2)
plt.plot(t[:1000], sum_sin[:1000], color='green', label='sin(ω₁t) + sin(ω₂t)')
plt.title('Addition of Sine Waves')
plt.legend(), plt.grid()

# 3. sin(ω₁t) × sin(ω₂t)
plt.subplot(6, 1, 3)
plt.plot(t[:1000], prod_sin[:1000], color='red', label='sin(ω₁t) × sin(ω₂t)')
plt.title('Product of Sine Waves')
plt.legend(), plt.grid()

# 4. 和積・積和
plt.subplot(6, 1, 4)
plt.plot(t[:1000], sum_to_prod[:1000], color='purple', label='Sum-to-Product')
plt.plot(t[:1000], prod_to_sum[:1000], color='orange', linestyle='--', label='Product-to-Sum')
plt.title('Sum-to-Product vs Product-to-Sum')
plt.legend(), plt.grid()

# 5. 倍角（sin, cos）
plt.subplot(6, 1, 5)
plt.plot(t[:1000], double_sin[:1000], label='sin(2ω₁t)', color='blue')
plt.plot(t[:1000], double_cos[:1000], label='cos(2ω₁t)', color='gray')
plt.title('Double Angle Formulas: sin(2ωt), cos(2ωt)')
plt.legend(), plt.grid()

# 6. 加法定理（sin(a+b), cos(a+b)）
plt.subplot(6, 1, 6)
plt.plot(t[:1000], sin_add[:1000], label='sin(ω₁t + ω₂t)', color='teal')
plt.plot(t[:1000], cos_add[:1000], label='cos(ω₁t + ω₂t)', color='goldenrod')
plt.title('Addition Formulas: sin(a+b), cos(a+b)')
plt.legend(), plt.grid()

plt.tight_layout()
plt.show()

# 🎧 音声再生（基本・加算・積・和積・積和・倍角・加法定理）
print("🎧 sin(ω₁t) [ド]")
display(Audio(normalize(sin1), rate=fs))

print("🎧 sin(ω₂t) [レ]")
display(Audio(normalize(sin2), rate=fs))

print("🎧 sin(ω₁t) + sin(ω₂t) [和音]")
display(Audio(normalize(sum_sin), rate=fs))

print("🎧 sin(ω₁t) × sin(ω₂t) [積]")
display(Audio(normalize(prod_sin), rate=fs))

print("🎧 和積公式 [sin + sin → sin × cos]")
display(Audio(normalize(sum_to_prod), rate=fs))

print("🎧 積和公式 [sin × sin → cos − cos]")
display(Audio(normalize(prod_to_sum), rate=fs))

print("🎧 sin(2ω₁t) [倍角]")
display(Audio(normalize(double_sin), rate=fs))

print("🎧 cos(2ω₁t) [倍角]")
display(Audio(normalize(double_cos), rate=fs))

print("🎧 sin(ω₁t + ω₂t) [加法定理: sin]")
display(Audio(normalize(sin_add), rate=fs))

print("🎧 cos(ω₁t + ω₂t) [加法定理: cos]")
display(Audio(normalize(cos_add), rate=fs))

```

## 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046871/db143454-0fd1-4411-9b07-f4c866eebc60.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046871/0feb9394-6ef5-433b-a040-cd5952e2c9c0.png)