今回のテーマ
以前、ノコギリ波を秒間440回繰り返して音を出したときの波のデータについて、どのような周波数が含まれているのかを調べてみる。
(前回挙げた疑問点の残るひとつは、とりあえず保留して次回以降へ)
やってみた
p10_1.py
# -*- coding: utf-8 -*-
import sys
sys.dont_write_bytecode = True
from Grp import Line, Bar
import Dummy as dmy
import numpy as np
import Analyze as ana
from multiprocessing import Process
import time
import math
def main():
orgsmpl = 44100 # サンプリングレートは44.1KHz
sec = 1 # 1秒分
# ノコギリ波
# -> 440回繰り返したいので、サンプル数を440分の1にして、あとで440回繰り返す
smpl = int(orgsmpl / 440)
wav1 = dmy.makeWave(1, smpl, sec, 0, 0, 1)
for i in range(64):
freq = i + 1
wav1 += dmy.makeWave(freq, smpl, sec, 1 / freq, 0, 1)
# 440回繰り返す
wav2 = np.array(list(wav1) * 440) * 16
# Hz 1~600で、解析
rng = (1, 600)
res = ana.ft(wav2, orgsmpl, (0, 1), rng)
res_sin = res[0]
res_cos = res[1]
# sinとcosの係数を2乗して加算して平方根をとる
res_all = list(map(
lambda v : math.sqrt(v),
np.array(res_sin) * np.array(res_sin) + np.array(res_cos) * np.array(res_cos)))
# 表示
p_s = []
p = Process(target=drawLineGraph, args=(wav2, smpl))
p.start()
p_s.append(p)
p = Process(target=drawBarGraph, args=(res_all, range(rng[0], rng[1] + 1)))
p.start()
p_s.append(p)
while len(p_s) > 0:
for p in p_s:
if not p.is_alive():
p.join()
p_s.remove(p)
time.sleep(0.1)
return
# 折れ線グラフの表示
def drawLineGraph(data, rate):
grp = Line()
grp.setData(data, rate)
grp.setScale(1)
grp.display()
# 棒グラフの表示
def drawBarGraph(data, label):
grp = Bar()
grp.setDataLabel(data, label)
grp.display()
if __name__ == '__main__':
main()
なお、それなりに計算量が多いので、実行すると、ちょっと時間がかかります。
437Hzあたりが多いらしい。440Hzがラなので、ほんの少しだけ低い音だったようだ(プログラムに間違いが無ければだが)。
補足
Grp.pyはここにあります。
https://qiita.com/u1tym/items/b52c466620f65225edf3
Dummy.pyはここにあります。
https://qiita.com/u1tym/items/3e2be5364e83df1b7792
Analyze.py、Integral.pyはここにあります。
https://qiita.com/u1tym/items/6fadd6b2974fc3281137