Pythonで音を出す。ドレミファソラシドを合成。

昨日作ったコードを流用して、同じオクターブの「ドレミファソラシド」を足し合わせて音を出してみました。(2023.07.01 by Kero)
何だか振動して、あまり心地よくない音になりました。
【音が出ます。音量にご注意ください。】

# sound-try-03.py    2023.07.01  by Kero
# "sounddevice" モジュールを使って音を出します。
# 「ドレミファソラシド」を同時に出します。

import numpy as np
import sounddevice as sd
import matplotlib.pyplot as plt
import scipy # 音のファイルを作るため。
from scipy.io.wavfile import write
import time
pi = np.pi

# 波形をグラフ化しています。(蛇足)
fig = plt.figure(figsize=(8,4)) # グラフを左右2枚。
ax1 = fig.add_subplot(121) # 左のグラフは音の出だしの波形。
ax2 = fig.add_subplot(122) # 右のグラフは音の終端の波形。

# CDのサンプリングレート(44100Hz)に合わせます。1秒間音が出ます。
sh = np.linspace(0, 1, 44101) # 時間軸です。
sndall = [0]*44101 # 振幅を入れる配列を用意します。

do = [0]*8 # 8つの音を用意します。
dg = 261.626 # Hz。高さから言って、このくらいの「ド」からが適当。

do[0] = dg # 「ド」。
do[1] = dg * 9/8  # 「レ」
do[2] = dg * 5/4  # 「ミ」
do[3] = dg * 4/3  # 「ファ」
do[4] = dg * 3/2  # 「ソ」
do[5] = dg * 5/3  # 「ラ」
do[6] = dg * 15/8 # 「ㇱ」
do[7] = dg * 2.0  # 「ド」

dodo = np.array([]) # 音を追加する器です。

a = 1. # 音量パラメータです。ノイズ除去に使います。
ax1.set_xlim(0, 4/440) # 波形グラフはラ(440Hz)の音が4つ入るくらいに設定。
ax2.set_xlim(1-4/440, 1) # 音の終端のグラフ用です。
for doi in do:
    print(doi)
    snd = np.sin(2*pi*sh*doi) # 各音を生成。
    for a in range(0, 750): # 音の終端にノイズが入るので、音量を小さくして消去。
        snd[-a-1] = snd[-a-1] * a / 750

    sd.play(snd, 44100) # 「ドレミファソラシド」の音を別々に出力。
    time.sleep(2) # ある音と次の音の間隔を2秒に設定。
    dodo = np.append(dodo, snd)
    sndall = sndall + snd # 各音を重ね合わせ。
    ax1.plot(sh, snd) # 各音の波形グラフ。0秒〜。
    ax2.plot(sh, snd) # 各音の波形グラフ。〜1秒。    

print("all")
sd.play(sndall, 44100) # 「ドレミファソラシド」を合わせて出力。
time.sleep(2)
dodo = np.append(dodo, sndall)

ax1.plot(sh, sndall) # 音の波形グラフ。0秒〜。
ax2.plot(sh, sndall) # 音の波形グラフ。〜1秒。

dodo = np.array(dodo)
# scipyはwav形式しか扱えないようです。別途、mp3に変換します。
scipy.io.wavfile.write(filename='sound-try-03.wav', rate=44100, data=dodo)

plt.show()