コードをコピーし、読者の開発環境で貼り付けてご使用ください。
目次
- 2-4 2音を鳴らすwavファイルを作る
- 2-6 平均律、純正律のドミソの和音を聞き比べる
- 2-7 周波数の近い2音を鳴らしてうなりを確認する
- 2-8 プッシュボタンを使わずに電話をかけられるか
- 2-10 wavファイルのパラメータを読み取る
- 2-11 matplotlibモジュールでグラフを描く
- 3-1 wavファイルで、サウンドデータの符号を一斉に反転する
- 3-2-1 クリッピングされたデータでグラフを描く
- 3ー2-2 wavファイルでクリッピングする
- 3-3 逆再生する、ドレミファソラシドを鳴らす
- 3-4 変声機の原理を確認する
- 4-5 SciPyのFFT、IFFTを使ったわかりやすい例(1)
- 4-6 SciPyのFFT、IFFTを使ったわかりやすい例(2)
- 4-7 SciPyのFFT、IFFTを使ったわかりやすい例(3)
- 4-8 SciPyのFFT、IFFTを使ったわかりやすい例(4)
- 5-1 ノイズ入りのサウンドからノイズを消す
- 5-2 ノイズ入りの信号から周波数成分を見つける
- 5-3 肉声を電話の声に変換する
- 5ー4 FFTは信用できるのか
- 5-5 Pythonでリアルタイムに動くグラフを描く
- 5-6 変化する周波数成分を表示する
- 6-1 離散フーリエ係数の値を変える際の注意点
- 6-2 最も基本的なイコライザを作る
2-4 2音を鳴らすwavファイルを作る
#==================
#waveファイルを作る。左は440Hz、右は700Hzで10秒間。
#
import sys
import wave
import numpy as np
import datetime
dt = datetime.datetime.now()
print('▼▼▼▼ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
pi = np.pi
fs = 44100 #サンプリング周波数
s = 10 #10秒の長さのwaveファイルを作る
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = fs * s #フレーム数(左右で1フレーム)
t = np.arange(0, s, 1/fs) #横軸
#sin(2π*□*t) の周波数は□の部分。16ビットで録音するので、
#-32768~32767がデータの範囲。だから-15000~15000の範囲の
#大きさの音を作ることにした。
ldata = 15000 * np.sin(2*pi*440*t) #440Hz
rdata = 15000 * np.sin(2*pi*700*t) #700Hz
sounddata = np.zeros(N * 2, dtype= "int16") #左右のデータ分が必要
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
dt = datetime.datetime.now()
print('▲▲▲▲ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
sys.exit()
#==================
2-6 平均律、純正律のドミソの和音を聞き比べる
#==================
#wavファイルを作る。ドミソの和音。
#
import sys
import numpy as np
import wave
pi = np.pi
fs = 22050 #サンプリング周波数
s = 20 #20秒の長さのwaveファイルを作る
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = fs * s #フレーム数
t = np.arange(0, s, 1/fs) #横軸
#sin(2π*□*t) の周波数は□の部分。16ビットで録音するので、
#-32768~32767がデータの範囲であることに注意。
#この範囲の外に出ると音が潰れる。
do = 523.3 #ドの音の周波数
r12 = 2 ** (1/12) #2の12乗根(≒1.059463094)
#--------------
# A
#
#純正律でドミソ
#ldata = 10000 * np.sin(2*pi*do*t) + 10000 * np.sin(2*pi*do*5/4*t)
#rdata = 10000 * np.sin(2*pi*do*3/2*t)
#--------------
# B
#
#平均律でドミソ
ldata = 10000 * np.sin(2*pi*do*t) + 10000 * np.sin(2*pi*do*(r12**4)*t)
rdata = 10000 * np.sin(2*pi*do*(r12**7)*t)
#--------------
sounddata = np.zeros(N * 2, dtype= "int16") #左右のデータ分が必要
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#==================
2-7 周波数の近い2音を鳴らしてうなりを確認する
#==================
import sys
import numpy as np
import wave
pi = np.pi
fs = 22050 #サンプリング周波数
s = 20 #20秒の長さのwavファイルを作る
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = fs * s #フレーム数
t = np.arange(0, s, 1/fs) #横軸
#sin(2π*□*t) の周波数は□の部分。16ビットで録音するので、
#-32768~32767がデータの範囲であることに注意。
#この範囲の外に出ると音が潰れる。
do = 523.3 #ドの音の周波数
r12 = 2 ** (1/12) #2の12乗根
#--------------
ldata = 15000 * np.sin(2*pi*do*5/4*t) #左スピーカー。純正律でミ
rdata = 15000 * np.sin(2*pi*do*(r12**4)*t) #右スピーカー。平均律でミ
#--------------
sounddata = np.zeros(N * 2, dtype= "int16") #左右のデータ分が必要
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#==================
2-8 プッシュボタンを使わずに電話をかけられるか
#==================
#wavファイルを作る。1をプッシュ
#
import sys
import numpy as np
import wave
pi = np.pi
fs = 22050 #サンプリング周波数
s = 20 #20秒の長さのwavファイルを作る
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = fs * s #フレーム数
t = np.arange(0, s, 1/fs) #横軸
#sin(2π*□*t) の周波数は□の部分。16ビットで録音するので、
#-32768~32767がデータの範囲であることに注意。
#この範囲の外に出ると音が潰れる。
#----------------------
#1……697Hz、1209Hz
#7……852Hz、1209Hz
#
#697の部分を852に書き換えると「7」になる
ldata = 15000 * np.sin(2*pi*697*t)
rdata = 15000 * np.sin(2*pi*1209*t) #1209は1,7で共通
#----------------------
sounddata = np.zeros(N * 2, dtype= "int16") #左右のデータ分が必要
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#==================
2-10 wavファイルのパラメータを読み取る
#==================
import sys
import datetime
import wave
dt = datetime.datetime.now()
print('▼▼▼▼ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
wavefile= wave.open("C:\\Users\\xxxx\\Desktop\\sound\\'yyyy.wav","rb")
print('■parameter = ', wavefile.getparams())
print('■framerate = ', wavefile.getframerate())
wavefile.close()
dt = datetime.datetime.now()
print('▲▲▲▲ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
sys.exit()
#==================
2-11 matplotlibモジュールでグラフを描く
1本目
#================== #グラフを描画する import numpy as np import matplotlib.pyplot as plt t = np.arange(0, 1, 0.2) y = t * t plt.plot(y) plt.show() #==================
2本目
#================== import numpy as np import matplotlib.pyplot as plt t = np.arange(0, 1, 0.2) y = t * t plt.plot(t, y) plt.show() #==================
3本目
#================== import numpy as np import matplotlib.pyplot as plt pi = np.pi #円周率、π N = 100 #1秒でデータ100個 t = np.arange(0, 1, 1/N) #時刻0以上1秒未満、1/N秒刻みの時刻の配列 #A y = np.sin(2*pi*4*t) #周波数は4Hz #B #y = np.sin(2*pi*4*t)+2*np.sin(2*pi*10*t) #周波数は4Hz,10Hz plt.plot(t, y) #波形を描画 plt.show() #==================
3-1 wavファイルで、サウンドデータの符号を一斉に反転する
#==================
import sys
import numpy as np
import wave
wavefile = wave.open("BGM.wav", "rb")
buf = wavefile.readframes(wavefile.getnframes())#サウンドデータ部分の読み取り
buf = np.frombuffer(buf, dtype= "int16")#16bit符号付き整数に変換
params = wavefile.getparams()
wavefile.close()
print(params)
if params.sampwidth != 2:
sys.exit() #16ビットで記録していなければ終了
sounddata = buf.copy() #サウンドデータの操作用バッファ
print(sounddata)
sounddata = -sounddata #サウンドデータの符号を一斉に反転
print(sounddata) #サウンドデータを見てみる
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
writewave.setparams(wavefile.getparams()) #保存先にパラメータをセット
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#==================
3-2-1 クリッピングされたデータでグラフを描く
#================== import numpy as np import matplotlib.pyplot as plt pi = np.pi #円周率、π N = 1000 #1秒でデータ1000個 t = np.arange(0, 1, 1/N) #0以上1秒未満、1/N秒刻みの時刻の配列 y = np.sin(2*pi*2*t) #周波数は2Hz y[y < -0.8] = -0.8 y[y > 0.8] = 0.8 plt.ylim(-1, 1) plt.plot(t, y) #波形を描画 plt.show() #==================
3ー2-2 wavファイルでクリッピングする
#==================
#クリッピング
#
import sys
import wave
import numpy as np
import datetime
#-------------------------------------------------
dt = datetime.datetime.now()
print('▼▼▼▼ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
wavefile = wave.open("C:\\Users\\xxxx\\Desktop\\BGM.wav","rb")
params = wavefile.getparams()
if params.sampwidth != 2:
wavefile.close()
sys.exit() #16ビットで記録していなければ終了
nframes = params.nframes #フレーム数の取得
buf = wavefile.readframes(nframes) #サウンドデータの読み取り
buf = np.frombuffer(buf, dtype= "int16") #16bit符号付き整数に変換
wavefile.close()
bufcopy = buf.copy()
lim = 1000
bufcopy[bufcopy > lim] = lim
bufcopy[bufcopy < -lim] = -lim
writewave = wave.Wave_write("C:\\Users\\xxxx\\Desktop\\keshitene.wav")
writewave.setparams(params) #元のwavファイルと同じパラメータをセット
writewave.writeframes(bufcopy) #編集したサウンドデータを保存
writewave.close()
dt = datetime.datetime.now()
print('▲▲▲▲ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
sys.exit()
#==================
3-3 逆再生する、ドレミファソラシドを鳴らす
逆再生する
#==================
#逆再生
#
import sys
import wave
import numpy as np
import datetime
dt = datetime.datetime.now()
print('▼▼▼▼ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
wavefile = wave.open("C:\\Users\\xxxx\\Desktop\\keshitene.wav","rb")
params = wavefile.getparams()
nframes = params.nframes #フレーム数の取得
if (params.sampwidth != 2):
wavefile.close()
sys.exit() #16ビットで記録していなければ終了
buf = wavefile.readframes(nframes) #サウンドデータの読み取り
buf = np.frombuffer(buf, dtype= "int16") #16bit符号付き整数に変換
wavefile.close()
buf1 = np.zeros(buf.size, dtype = "int16")
for i in range(buf.size): #bufの内容を逆転してbuf1へ格納
buf1[i] = buf[buf.size - i - 1]
writewave= wave.Wave_write("C:\\Users\\xxxx\\Desktop\\keshitene.wav")
writewave.setparams(params)
writewave.writeframes(buf1) #編集したサウンドデータを保存
writewave.close()
#
dt = datetime.datetime.now()
print('▲▲▲▲ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
sys.exit()
#==================ドレミファソラシドを鳴らす
#==================
#wavファイルを作る。ドレミファソラシド
#
import sys
import numpy as np
import wave
import datetime
dt = datetime.datetime.now()
print('▼▼▼▼ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
pi = np.pi
fs = 22050 #サンプリング周波数
s = 0.5
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = int(fs * s) #フレーム数
t = np.arange(0, s, 1/fs) #横軸
do = 523.3 #ドの音の周波数
x = do
r12 = 2 ** (1/12) #2の12乗根(≒1.059463094)
#--------------
#平均律でドレミファソラシド
ldata = 15000 * np.sin(2*pi*x*t) #ド
x = x * r12 * r12
ldata = np.concatenate([ldata, 15000 * np.sin(2*pi*x*t)]) #レ
x = x * r12 * r12
ldata = np.concatenate([ldata, 15000 * np.sin(2*pi*x*t)]) #ミ
x = x * r12
ldata = np.concatenate([ldata, 15000 * np.sin(2*pi*x*t)]) #ファ
x = x * r12 * r12
ldata = np.concatenate([ldata, 15000 * np.sin(2*pi*x*t)]) #ソ
x = x * r12 * r12
ldata = np.concatenate([ldata, 15000 * np.sin(2*pi*x*t)]) #ラ
x = x * r12 * r12
ldata = np.concatenate([ldata, 15000 * np.sin(2*pi*x*t)]) #シ
x = x * r12
ldata = np.concatenate([ldata, 15000 * np.sin(2*pi*x*t)]) #ド
rdata = ldata
sounddata = np.zeros(int(N*2*8), dtype= "int16")
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave= wave.Wave_write("C:\\Users\\xxxx\\Desktop\\keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
dt = datetime.datetime.now()
print('▲▲▲▲ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
sys.exit()
#==================
3-4 変声機の原理を確認する
#==================
#左のスピーカーからA-Bが流れ、右から Bが流れるwavファイル
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
import wave
import datetime
dt = datetime.datetime.now()
print('▼▼▼▼ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
#音楽A
wavefile = wave.open("C:\\Users\\xxxx\\Desktop\\音楽A.wav","rb") #こちらの方が長い曲
params = wavefile.getparams()
if (params.sampwidth != 2) or (params.nchannels != 2):
wavefile.close()
sys.exit() #16ビットで記録していないか、ステレオでなければ終了
#サウンドデータ部分の読み取り
buf = wavefile.readframes(wavefile.getnframes())
buf = np.frombuffer(buf, dtype= "int16")#16bit符号付き整数に変換
print(wavefile.getparams())
wavefile.close()
sdata = buf.copy()
ldata = sdata[0::2] #左のデータ
rdata = sdata[1::2] #右のデータ
#音楽B
#こちらの方が短い曲
wavefile1 = wave.open("C:\\Users\\xxxx\\Desktop\\音楽B.wav","rb")
params = wavefile1.getparams()
if (params.sampwidth != 2) or (params.nchannels != 2):
wavefile1.close()
sys.exit() #16ビットで記録していないか、ステレオでなければ終了
#サウンドデータ部分の読み取り
buf = wavefile1.readframes(wavefile1.getnframes())
buf = np.frombuffer(buf, dtype= "int16")#16bit符号付き整数に変換
print(wavefile1.getparams())
wavefile1.close()
sdata1 = buf.copy()
ldata1 = sdata1[0::2] #左のデータ
rdata1 = sdata1[1::2] #右のデータ
soundLen = rdata1.size #短い方の曲の長さ
#2つの曲(A,B)ともステレオの右のデータだけを使う
#rdataにはA-B、ldataにはBを入れる
rdata[:soundLen] = rdata[:soundLen]//2 - rdata1//2 #A-B を入れる
ldata[:soundLen] = rdata1//2 #B を入れる
sdata[0::2] = ldata
sdata[1::2] = rdata
writewave = wave.Wave_write("C:\\Users\\xxxx\\Desktop\\keshitene.wav")
writewave.setparams(wavefile.getparams()) #保存先にパラメータをセット
writewave.writeframes(sdata) #編集したサウンドデータを保存
writewave.close()
dt = datetime.datetime.now()
print('▲▲▲▲ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
sys.exit()
#==================
4-5 SciPyのFFT、IFFTを使ったわかりやすい例(1)
#================== import numpy as np import scipy as sp from scipy.fftpack import fft import matplotlib.pyplot as plt pi = np.pi fs = 600 #サンプリング周波数 N = 200 #サンプル数 t = np.arange(0, N/fs, 1/fs) #1/fs秒刻みの時刻の配列 y = np.sin(2*pi*30*t)+2*np.sin(2*pi*45*t) #周波数は30Hz,45Hz plt.ylim(-4, 4) #描画するy軸の範囲をセット plt.plot(t, y) #元の波形を描画 plt.show() #yf[k]には第k次高調波のフーリエ係数が入る yf = sp.fftpack.fft(y[:N]) plt.plot(np.abs(yf)) #含まれる周波数成分を描画 plt.show() yf[10] = 0 #第10次高調波をカット yf[N-10] = 0 #第10次高調波をカット yif = sp.fftpack.ifft(yf[:N]).real plt.ylim(-4, 4) plt.plot(t, yif) plt.show() #==================
4-6 SciPyのFFT、IFFTを使ったわかりやすい例(2)
#================== import numpy as np import scipy as sp from scipy.fftpack import fft import matplotlib.pyplot as plt # fs = 600 t = np.arange(0, 6, 1/fs) y= np.sin(2*np.pi*50*t)+2*np.sin(2*np.pi*80*t)+3*np.sin(2*np.pi*100*t) yf = sp.fftpack.fft(y[:300]) plt.plot(np.abs(yf)) plt.show() #==================
4-7 SciPyのFFT、IFFTを使ったわかりやすい例(3)
#================== import numpy as np import scipy as sp from scipy.fftpack import fft import matplotlib.pyplot as plt pi = np.pi fs = 100 #サンプリング周波数 N = fs #サンプル数はfsとする t = np.arange(0, 1, 1/fs) #1/fs秒刻みの時刻の配列。基本周期T = 1。 y = np.sin(2*pi*4*t)+2*np.sin(2*pi*10*t) #周波数は4Hz,10Hz plt.plot(t, y) #元の波形を描画 plt.show() #yf[k]には第k次高調波のフーリエ係数が入る yf = sp.fftpack.fft(y[:N]) plt.plot(np.abs(yf)) #含まれる周波数成分を描画 plt.show() yif = sp.fftpack.ifft(yf[:N]).real #ifftで元の波形に戻してみる plt.plot(t, yif) #戻ったか、確認。最初と同じグラフのはず plt.show() yf[10] = 0 #第10次高調波をカット yf[N-10] = 0 #第10次高調波をカット #t = np.arange(0, 1, 1/fs) #1/fs秒刻みの時刻の配列。基本周期T = 1。 yif = sp.fftpack.ifft(yf[:N]).real plt.plot(t, yif) plt.show() yf1 = sp.fftpack.fft(yif[:N]) #10次はカットしてある plt.plot(np.abs(yf1)) #周波数成分を調べる plt.show() #==================
4-8 SciPyのFFT、IFFTを使ったわかりやすい例(4)
#================== import numpy as np import scipy as sp from scipy.fftpack import fft import matplotlib.pyplot as plt pi = np.pi #周期T = 3秒。基本周波数=1/3Hz。 fs = 40 #サンプリング周波数。データ1個で1/40秒。 N = 120 #データ数は3/(1/40)=120 #tは1/40秒刻みの時刻の配列。1/40秒ごとに3秒間、サンプリング t = np.arange(0, 3, 1/40) tt = np.arange(0, 120) #要素は0から1刻みで119まで y = np.sin(2*pi*4*t)+2*np.sin(2*pi*10*t) #周波数は4Hz,10Hz plt.plot(t, y) #元の波形を描画 plt.show() #yf[k]には第k次高調波のフーリエ係数が入る yf = sp.fftpack.fft(y[:N]) #配列 tt には0,1,2,……, 119 が入っている #yf[k]には第k次高調波(周波数はk/3 Hz)の成分が入るので、 #横軸の目盛りを= tt / 3.0 とすれば周波数が表示される plt.plot(tt / 3.0, np.abs(yf)) #含まれる周波数成分を描画 plt.show() #==================
5-1 ノイズ入りのサウンドからノイズを消す
1本目
#==================
#ノイズ入りのwavファイルを作る。左は440Hz、右は700Hzで10秒間。
#
import scipy as sp
import sys
import numpy as np
import wave
from scipy.fftpack import fft
import matplotlib.pyplot as plt
pi = np.pi
fs = 44100 #サンプリング周波数
s = 10 #10秒の長さのwavファイルを作る
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = fs * s #フレーム数(左右ひと組で1フレーム)
t = np.arange(0, s, 1/fs) #横軸の配列を作る
#sin(2π*□*t) の周波数は□の部分。16ビットで録音するので、
#-32768~32767がデータの範囲。だから-15000~15000の範囲の
#大きさの音を作ることにした。
#
#440Hzの音+ノイズ
ldata = 15000 * np.sin(2*pi*440*t) + 2500 *np.random.randn(t.size)
#700Hzの音+ノイズ
rdata = 15000 * np.sin(2*pi*700*t) + 2500 * np.random.randn(t.size)
#配列のサイズは左、右のサイズの和
sounddata = np.zeros(N * 2, dtype = "int16")
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#==================2本目
#==================
#ノイズ入りのwavファイルを作る。左は440Hz、右は700Hzで10秒間。
#
import scipy as sp
import sys
import numpy as np
import wave
from scipy.fftpack import fft
import matplotlib.pyplot as plt
pi = np.pi
fs = 44100 #サンプリング周波数
s = 10 #10秒の長さのwavファイルを作る
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = fs * s #フレーム数
t = np.arange(0, s, 1/fs) #横軸の配列を作る
#sin(2π*□*t) の周波数は□の部分。16ビットで録音するので、
#-32768~32767がデータの範囲。だから-15000~15000の範囲の
#大きさの音を作ることにした。
#440Hzの音+ノイズ
ldata = 15000 * np.sin(2*pi*440*t) + 2500 *np.random.randn(t.size)
#700Hzの音+ノイズ
rdata = 15000 * np.sin(2*pi*700*t) + 2500 * np.random.randn(t.size)
#■■■
yf = sp.fftpack.fft(ldata[:N])
plt.plot(abs(yf))
plt.show()
#■■■
#配列のサイズは左、右のサイズの和
sounddata = np.zeros(N * 2, dtype = "int16")
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#==================3本目
#==================
#ノイズ入りのwavファイルを作る。左は440Hz、右は700Hzで10秒間。
#
import scipy as sp
import sys
import numpy as np
import wave
from scipy.fftpack import fft
import matplotlib.pyplot as plt
pi = np.pi
fs = 44100 #サンプリング周波数
s = 10 #10秒の長さのwavファイルを作る
#s秒分のサウンドデータを作るには、fs*sフレームが必要。
N = fs * s #フレーム数
t = np.arange(0, s, 1/fs) #横軸の配列を作る
#sin(2π*□*t) の周波数は□の部分。16ビットで録音するので、
#-32768~32767がデータの範囲。だから-15000~15000の範囲の
#大きさの音を作ることにした。
#440Hzの音+ノイズ
ldata = 15000 * np.sin(2*pi*440*t) + 2500 *np.random.randn(t.size)
#700Hzの音+ノイズ
rdata = 15000 * np.sin(2*pi*700*t) + 2500 * np.random.randn(t.size)
#■■■
yf = sp.fftpack.fft(ldata[:N])
yf[abs(yf) < 7500000] = 0 #yfの絶対値が750万未満のデータは0に
ldata = sp.fftpack.ifft(yf[:N]).real
yf = sp.fftpack.fft(rdata[:N])
yf[abs(yf) < 7500000] = 0 #yfの絶対値が750万未満のデータは0に
rdata = sp.fftpack.ifft(yf[:N]).real
#■■■
#配列のサイズは左、右のサイズの和
sounddata = np.zeros(N * 2, dtype = "int16")
sounddata[0::2] = ldata
sounddata[1::2] = rdata
writewave = wave.Wave_write("keshitene.wav") #保存先ファイル
#setparamの引数は
#(nchannels, sampwidth, framerate, nframes, comptype, compname)
#先頭から順にステレオ、サンプルのサイズ2バイト、
#サンプリング周波数fs、フレーム数N。
writewave.setparams((2, 2, fs, N, 'NONE', 'NONE'))
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#==================
5-2 ノイズ入りの信号から周波数成分を見つける
#================== import sys import numpy as np import scipy as sp from scipy.fftpack import fft import matplotlib.pyplot as plt pi = np.pi fs = 1000 #サンプリング周波数 N = fs * 4 #サンプル数 t = np.arange(0, 4, 1/fs) #1/fs秒刻みの時刻の配列(4秒間) #100Hz,440Hz の信号にノイズを混ぜる y=np.sin(2*pi*100*t)+1.5*np.sin(2*pi*440*t)+3* np.random.randn(t.size) plt.plot(t, y) #元の波形を描画 plt.show() #yf[k]には第k次高調波のフーリエ係数が入る yf = sp.fftpack.fft(y[:N]) #得られる最大の周波数成分は fs = 1000ヘルツ。 #つまりFFTの結果のグラフの右端は fs = 1000ヘルツの成分。 plt.plot(np.abs(yf)) #含まれる周波数成分を描画 plt.show() sys.exit() #==================
5-3 肉声を電話の声に変換する
#==================
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
import wave
N = 8192 #FFTするサイズ。2の13乗。
#
#--------------------------------
#サウンドデータの高域成分をカットする関数
#
#databuf: サウンドデータの入ったバッファ
#num1: 第num1次高調波から第num2高調波までを残して消す
def editsound(databuf, num1, num2):
databuf1 = np.zeros(databuf.size)
for i in range(int(databuf.size / N)):
#databufの先頭から順にNデータずつ処理
databuf2 = databuf[N * i: N * (i+1)] #Nデータを取り出す
yf = sp.fftpack.fft(databuf2)
for j in range(1, num1):
yf[j] = 0 #低周波成分を0に
yf[N - j] = 0
for j in range(num2+1, int(N/2)):
yf[j] = 0 #高周波成分を0に
yf[N - j] = 0
#ifftの結果は複素数。もとが実データなので結果の虚数部分は0。
#コピー先は複素数の配列ではないので実数部分だけをコピーする。
databuf1[N * i: N * (i+1)] = sp.fftpack.ifft(yf).real
return databuf1
#--------------------------------
#メインルーチン
wavefile = wave.open("人の声.wav","rb")
#サウンドデータ部分の読み取り
buf = wavefile.readframes(wavefile.getnframes())
buf = np.frombuffer(buf, dtype= "int16") #16bit符号付き整数に変換
params = wavefile.getparams()
wavefile.close()
print(params)
if (params.sampwidth != 2) or (params.nchannels != 2):
sys.exit() #16ビットで記録していないか、ステレオでなければ終了
sounddata = buf.copy() #サウンドデータ用バッファ
sounddata[0::2] = editsound(sounddata[0::2], 56, 631) #左の音を編集
sounddata[1::2] = editsound(sounddata[1::2], 56, 631) #右の音を編集
writewave = wave.Wave_write("電話の声.wav") #保存先ファイル名
writewave.setparams(wavefile.getparams()) #同じパラメータをセット
writewave.writeframes(sounddata) #編集したデータをファイルへ保存
writewave.close()
sys.exit()
#==================
5ー4 FFTは信用できるのか
#==================
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
import matplotlib.pyplot as plt
print("▼")
pi = np.pi
fs = 200 #サンプリング周波数
N = 600 #サンプル数
t = np.arange(0, N/fs, 1/fs) #1/fs秒刻みの時刻の配列
y = np.sin(2*pi*40*t)+2*np.sin(2*pi*90*t)
#yf[k]には第k次高調波のフーリエ係数が入る
yf = sp.fftpack.fft(y[:N])
plt.plot(np.abs(yf)) #含まれる周波数成分を描画
plt.show()
print("▲")
sys.exit()
#==================
5-5 Pythonでリアルタイムに動くグラフを描く
#==================
#リアルタイムにグラフを描画
#
import sys
import numpy as np
import matplotlib.pyplot as plt
pi = np.pi
t = np.arange(0, 3, 1/40) #横軸
for i in range(1,1000):
plt.ylim(-5, 5) #y軸の最小値、最大値をセット
y = 3*np.sin(2*pi*4*t+0.3*i)
plt.plot(t, y) #波形を描画
plt.pause(0.1) #pyplot.show()では1回描画して止まってしまう
plt.clf() #今描いたグラフを消す
sys.exit()
#==================
5-6 変化する周波数成分を表示する
#==================
#リアルタイムに周波数成分を描画
#
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
import matplotlib.pyplot as plt
pi = np.pi
N = 120 #データ数は3/(1/40)=120
# t は1/40秒刻み、0秒以上3秒未満の時刻の配列。
#周期T = 3秒。基本周波数=1/3Hz。サンプリング周波数は40Hz
t = np.arange(0, 3, 1/40)
for i in range(1,100):
y = np.sin(2*pi*(1/3*30)*t) + np.sin(2*pi*(1/3*10 + 0.1*i)*t)
yf = sp.fftpack.fft(y[:N])
#yf[k]には第k次高調波のフーリエ係数が入る
plt.plot(np.abs(yf)) #含まれる周波数成分を描画
plt.pause(0.1)
plt.clf()
sys.exit()
#==================
6-1 離散フーリエ係数の値を変える際の注意点
1本目
#==================
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
y = [10, 20, 30, 40, 50, 60, 70, 80]
yf = sp.fftpack.fft(y) #yf[k]には第k次高調波のフーリエ係数が入る
for i in range(8):
print("■yf", i, yf[i])
yif = sp.fftpack.ifft(yf)
for i in range(8):
print("■■yif", i, yif[i])
sys.exit()
#==================2本目
#==================
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
y = [10, 20, 30, 40, 50, 60, 70, 80]
yf = sp.fftpack.fft(y) #yf[k]には第k次高調波のフーリエ係数が入る
for i in range(8):
print("■yf", i, yf[i])
yf[1] = 3-4j
yf[7] = 3+4j #yf[1]の共役複素数
yf[2] = 6j
yf[6] = -6j #yf[2]の共役複素数
yif = sp.fftpack.ifft(yf)
for i in range(8):
print("■■yif", i, yif[i])
sys.exit()
#==================3本目
#==================
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
y = [10, 20, 30, 40, 50, 60, 70, 80]
yf = sp.fftpack.fft(y) #yf[k]には第k次高調波のフーリエ係数が入る
for i in range(8):
print("■yf", i, yf[i])
yf[1] = 3-4j
yf[7] = 5 #yf[1]の共役複素数ではない
yf[2] = 6j
yf[6] = 1+3j #yf[2]の共役複素数ではない
yif = sp.fftpack.ifft(yf)
for i in range(8):
print("■■yif", i, yif[i])
sys.exit()
#==================
6-2 最も基本的なイコライザを作る
#==================
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
import wave
import datetime
N = 22050 #FFTするサイズ
#--------------------------------
#サウンドデータの、指定した周波数成分をrate倍する
#
#databuf: サウンドデータの入ったバッファ
#num1~num2次高調波の成分をrate倍にする。maxはN/2-1
def editSound(databuf, num1, num2, rate):
databuf1 = np.zeros(databuf.size)
for i in range(int(databuf.size / N)):
#Nデータずつ処理
yf = sp.fftpack.fft(databuf[N * i: N * (i+1)])
for j in range(num1, num2+1):
yf[j] = yf[j] * rate #周波数成分をrate倍に
yf[N - j] = yf[N - j] * rate
#ifftの結果は複素数。もとが実データなので結果の虚数部分は0。
#だがコピー先は実数の配列ではないので実数部分だけをコピーする。
databuf1[N * i: N * (i+1)] = sp.fftpack.ifft(yf).real
return databuf1
#--------------------------------
wavefile = wave.open("C:\\Users\\xxxx\\Desktop\\BGM.wav","rb")
#サウンドデータ部分の読み取り
buf = wavefile.readframes(wavefile.getnframes())
buf = np.frombuffer(buf, dtype= "int16") #16bit符号付き整数に変換
params = wavefile.getparams()
wavefile.close()
print(params)
if (params.sampwidth != 2) or (params.nchannels != 2):
sys.exit() #16ビットで記録していないか、ステレオでなければ終了
sounddata = buf.copy() #サウンドデータ用バッファ
#高音を編集
sounddata[0::2] = editSound(sounddata[0::2], 500, 5000, 0) #左を編集
sounddata[1::2] = editSound(sounddata[1::2], 500, 5000, 0) #右を編集
#低音を編集
sounddata[0::2] = editSound(sounddata[0::2], 1, 499, 1.2) #左を編集
sounddata[1::2] = editSound(sounddata[1::2], 1, 499, 1.2) #右を編集
#保存先
writewave = wave.Wave_write("C:\\Users\\xxxx\\Desktop\\keshitene.wav")
#保存先ファイルに元と同じパラメータをセット
writewave.setparams(wavefile.getparams())
writewave.writeframes(sounddata) #編集したサウンドデータを保存
writewave.close()
dt = datetime.datetime.now()
print('▲▲▲▲ {}:{}:{}'.format(dt.hour, dt.minute, dt.second))
sys.exit()
#==================
