Showing preview only (416K chars total). Download the full file or copy to clipboard to get everything.
Repository: masahitotogami/python_source_separation
Branch: master
Commit: e0788b02104e
Files: 74
Total size: 331.5 KB
Directory structure:
gitextract_ib0mjebm/
├── LICENSE.txt
├── README.md
├── errata.md
├── install.md
├── section10/
│ ├── sample_code_c10_1.py
│ └── sample_code_c10_2.py
├── section10.md
├── section11/
│ ├── sample_code_c11_1.py
│ └── sample_code_c11_2.py
├── section11.md
├── section2/
│ ├── sample_code_c2_1.py
│ ├── sample_code_c2_10.py
│ ├── sample_code_c2_11.py
│ ├── sample_code_c2_12.py
│ ├── sample_code_c2_13.py
│ ├── sample_code_c2_14.py
│ ├── sample_code_c2_2.py
│ ├── sample_code_c2_3.py
│ ├── sample_code_c2_4.py
│ ├── sample_code_c2_5.py
│ ├── sample_code_c2_6.py
│ ├── sample_code_c2_7.py
│ ├── sample_code_c2_8.py
│ └── sample_code_c2_9.py
├── section2.md
├── section3/
│ ├── sample_code_c3_1.py
│ ├── sample_code_c3_2.py
│ ├── sample_code_c3_3.py
│ ├── sample_code_c3_4.py
│ ├── sample_code_c3_5.py
│ ├── sample_code_c3_6.py
│ ├── sample_code_c3_7.py
│ ├── sample_code_c3_8.py
│ └── sample_code_c3_9.py
├── section3.md
├── section4/
│ └── sample_code_c4_1.py
├── section4.md
├── section5/
│ ├── sample_code_c5_1.py
│ ├── sample_code_c5_2.py
│ ├── sample_code_c5_3.py
│ ├── sample_code_c5_4.py
│ ├── sample_code_c5_5.py
│ ├── sample_code_c5_6.py
│ └── sample_code_c5_7.py
├── section5.md
├── section6/
│ ├── sample_code_c6_1.py
│ ├── sample_code_c6_10.py
│ ├── sample_code_c6_11.py
│ ├── sample_code_c6_12.py
│ ├── sample_code_c6_13.py
│ ├── sample_code_c6_14.py
│ ├── sample_code_c6_2.py
│ ├── sample_code_c6_3.py
│ ├── sample_code_c6_4.py
│ ├── sample_code_c6_5.py
│ ├── sample_code_c6_6.py
│ ├── sample_code_c6_7.py
│ ├── sample_code_c6_8.py
│ └── sample_code_c6_9.py
├── section6.md
├── section7/
│ ├── sample_code_c7_1.py
│ ├── sample_code_c7_2.py
│ ├── sample_code_c7_3.py
│ ├── sample_code_c7_4.py
│ └── sample_code_c7_5.py
├── section7.md
├── section8/
│ ├── sample_code_c8_1.py
│ ├── sample_code_c8_2.py
│ ├── sample_code_c8_3.py
│ └── sample_code_c8_4.py
├── section8.md
├── section9/
│ ├── sample_code_c9_1.py
│ └── sample_code_c9_2.py
└── section9.md
================================================
FILE CONTENTS
================================================
================================================
FILE: LICENSE.txt
================================================
MIT License
Copyright (c) 2020 Masahito Togami
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
## Pythonで学ぶ音源分離(機械学習実践シリーズ)のソースコード


本リポジトリでは、インプレス社機械学習実践シリーズの「Pythonで学ぶ音源分離」のサンプルコードを管理しています。
なお、本ソースコードは、MITライセンスのもとで公開されています。LICENSE.txtを見てください。
## 書籍概要

* [Pythonで学ぶ音源分離(機械学習実践シリーズ)](https://book.impress.co.jp/books/1119101154 "Pythonで学ぶ音源分離(機械学習実践シリーズ)")
* 価格: 3,500円+税
* 発売日: 2020年8月24日
* ページ数: 352
* サイズ: B5変形判
* 著者: 戸上 真人
* ISBN: 9784295009849
## 目次
* 序章
* 第1章 音源分離とは?
* 第2章 音声処理の基礎
* 第3章 音源分離で用いる数学的知識の基礎(線形代数、ベクトル・行列の微分)
* 第4章 「最適化」に関する技法を理解する
* 第5章 シミュレーターで音を作ってみる
* 第6章 古典的な音源分離方法~ビームフォーミング~
* 第7章 音源方向推定に基づく音源分離
* 第8章 現代的な統計的モデルに基づく音源分離法
* 第9章 響きのある音を響きのない音に変える残響除去法
* 第10章 音源分離と残響除去を統合的に実行する
* 第11章 音源分離関連のライブラリ紹介・その他のトピック・参考文献
## 各章のサンプルコード
* [本書の前提](install.md)
* [第2章のサンプルコード](section2.md)
* [第3章のサンプルコード](section3.md)
* [第4章のサンプルコード](section4.md)
* [第5章のサンプルコード](section5.md)
* [第6章のサンプルコード](section6.md)
* [第7章のサンプルコード](section7.md)
* [第8章のサンプルコード](section8.md)
* [第9章のサンプルコード](section9.md)
* [第10章のサンプルコード](section10.md)
* [第11章のサンプルコード](section11.md)
## お詫びと訂正
Pythonで学ぶ音源分離(機械学習実践シリーズ)に誤りがありました。ここに謹んでお詫び申し上げますと共に,以下のページに正誤表を
掲載させて頂きます。
[本書の正誤表](errata.md)
## License
MIT
================================================
FILE: errata.md
================================================
## 正誤表
|項番|該当箇所|誤|正|update|
|---|---|---|---|---|
|1|p.2| pip install itertools | 削除 |2020/08/24|
|2|第4章第5節タイトル, p4, p.135 | Maximization-Majorization | Majorization-Minimization | 2020/08/24|
|3|p.10| 「知り当たった」|「知り合った」|2020/08/24|
|4|第二章|code2.1とcode2.9が欠番。(コードを削除したことに起因)|-|2020/08/24|
|5|p.60|code2.14|code2.15|2020/08/24|
|6|p.97|code3.9|result3.1|2020/08/24|
|7|p.82| 「このとき、m<Mでβmは0となり、」|「このとき、m<Mでβmは0となることがありますが、」|2020/08/24|
|8|p.151| 図5.5 雑音・残響環境のスペクトログラム |図5.5 雑音・残響環境のスペクトログラム |2020/08/24|
|9|p.175| mic_alignments = np.array([ [[x,0.0,0.0] for x in np.arange(-0.31,0.32,0.02)] ] ) | mic_alignments = np.array( [[x,0.0,0.0] for x in np.arange(-0.31,0.32,0.02)] ) |2020/08/24|
|10|p.228| 「音声のスパース性に基づく音源分離の実行結果(マイクロホンの間隔40センチ)」|「マイクロホンの間隔を40センチに変更」|2020/08/24|
|11|p.238| 「スパース性を利用した音源分離の実行例(マイクロホン間隔40センチ)」|「スパース性を利用した音源分離の実行例(マイクロホン36素子)」|2020/08/24|
|12|p.326の表10-1の数値| LGM「14.69」、LGM+Dreverb「20.71」|LGM「13.89」、LGM+Dreverb「19.91」|2020/08/24|
|13|p.336の表10-2の数値| ILRMA「14.38」、ILRMA+Dereverb「19.62」、ILRMA-T「18.05」|ILRMA「13.58」、ILRMA+Dereverb「18.82」、ILRMA-T「17.25」|2020/08/24|
|14|p.340|「無残響環境と残響環境の二つの環境で実行しています。」 |「残響環境で実行しています。」|2020/08/24|
|15|p.311|式(9.2)と |最小二乗法と|2020/08/25|
|16|p.45|式(2.32)  |式(2.32)  |2020/08/27|
|17|p.46|式(2.36)  |式(2.36)  |2020/08/27|
|18|p.86|「単一行列 」|「大きさ1のベクトル」 |2020/08/27|
|19|p.124|「という考え方です。」 |「という考え方に基づいてパラメータを最適化します。」|2020/08/27|
|20|p.131|「と右辺が一致する(不等号の統合が成立する)」 |「であることから右辺が一致する(不等号の等号が成立する)」|2020/08/27|
|21|p.139|「パラメータ法」 |「パラメータ最適化法」|2020/08/27|
|22|p.41の5行目|「#複素共役を表示する」 |「#絶対値を表示する」|2020/11/13|
|23|p.40|式(2.11)  |式(2.11) |2021/05/25|
|24|p.343|I. Dokmani? |I. Dokmanic|2021/05/25|
|25|p.56|式(2.46)  |式(2.46) |2021/05/25|
|26|p.58|noise amp=np.power(np.mean(np.power(amp,p)[:,:n_noise_only_frame],axis=1,keepdims=True),1./2) |noise amp=np.power(np.mean(np.power(amp,p)[:,:n_noise_only_frame],axis=1,keepdims=True),1./p) |2021/05/25|
================================================
FILE: install.md
================================================
## 本書の前提
* 本書の全てのソースコードは、Python3.6.4を使って動作を確認しています。
* Python標準のライブラリ以外で必要となるライブラリをインストールする
コマンドを以下に示します。
```
$pip install numpy
$pip install scipy
$pip install matplotlib
$pip install sounddevice
$pip install pyroomacoustics
$pip install nara-wpe
```
================================================
FILE: section10/sample_code_c10_1.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
#順列計算に使用
import itertools
import time
#A: ...mn
#B: ...ij
#AとBの最後の二軸以外の次元は一致していることを前提とする
def batch_kron(A,B):
if np.shape(A)[:-2]!=np.shape(B)[:-2]:
print("error")
return None
else:
return(np.reshape(np.einsum("...mn,...ij->...minj",A,B),np.shape(A)[:-2]+(np.shape(A)[-2]*np.shape(B)[-2],np.shape(A)[-1]*np.shape(B)[-1])))
#x:入力信号( M, Nk, Lt)
#D:遅延フレーム数
#Lh:残響除去フィルタのタップ長
#return x_bar: 過去のマイク入力信号(Lh,M,Nk,Lt)
def make_x_bar(x,D,Lh):
#フレーム数を取得
Lt=np.shape(x)[2]
#過去のマイク入力信号の配列を準備
x_bar=np.zeros(shape=(Lh,)+np.shape(x),dtype=np.complex)
for tau in range(Lh):
x_bar[tau,...,tau+D:]=x[:,:,:-(tau+D)]
return(x_bar)
#IP法によるLGMのパラメータ推定法
#x:入力信号( M, Nk, Lt)
#Ns: 音源数
#n_iterations: 繰り返しステップ数
#return R 共分散行列(Nk,Ns,M,M) v 時間周波数分散(Nk,Ns,Lt),c_bar 音源分離信号(M,Ns,Nk,Lt), cost_buff コスト (T)
def execute_mm_lgm(x,Ns=2,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
#Rとvを初期化する
mask=np.random.uniform(size=Nk*Ns*Lt)
mask=np.reshape(mask,(Nk,Ns,Lt))
R=np.einsum("kst,mkt,nkt->kstmn",mask,x,np.conjugate(x))
R=np.average(R,axis=2)
v=np.random.uniform(size=Nk*Ns*Lt)
v=np.reshape(v,(Nk,Ns,Lt))
cost_buff=[]
for t in range(n_iterations):
#入力信号の共分散行列を求める
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V_inverse=np.linalg.pinv(V)
#コスト計算
cost=np.sum(np.einsum("mkt,ktmn,nkt->kt",np.conjugate(x),V_inverse,x) +np.log(np.abs(np.linalg.det(V))))
cost/=np.float(Lt)
cost=np.real(cost)
cost_buff.append(cost)
#パラメータを更新
#Rの更新
V_inverseX=np.einsum('ktmn,nkt->ktm',V_inverse,x)
V_inverseXV_inverseX=np.einsum('ktm,ktn->ktmn',V_inverseX,np.conjugate(V_inverseX))
A=np.einsum('kst,ktmn->ksmn',v,V_inverse)
B=np.einsum('kst,ktmn->ksmn',v,V_inverseXV_inverseX)
RBR=np.einsum('ksmn,ksni,ksij->ksmj',R,B,R)
invA=np.linalg.pinv(A)
A_RBR=np.matmul(A,RBR)
R=np.concatenate([np.concatenate([np.matmul(invA[k,s,...],scipy.linalg.sqrtm(A_RBR[k,s,...]))[None,None,...] for k in range(Nk)],axis=0) for s in range(Ns)],axis=1)
R=(R+np.transpose(np.conjugate(R),[0,1,3,2]))/(2.0+0.0j)
#vの更新
v=v*np.sqrt(np.einsum('ktm,ktn,ksnm->kst',V_inverseX,np.conjugate(V_inverseX),R)/np.maximum(np.einsum('ktmn,ksnm->kst',V_inverse,R) ,1.e-18))
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V_inverse=np.linalg.pinv(V)
Wmwf=np.einsum("kstmi,ktin->kstmn",vR,V_inverse)
#音源分離信号を得る
c_bar=np.einsum('kstmn,nkt->mskt',Wmwf,x)
return(R,v,c_bar,cost_buff)
#LGMの音源分離と残響除去のパラメータ推定法
#x:入力信号( M, Nk, Lt)
#x_bar:過去のマイク入力信号(Lh,M, Nk, Lt)
#Ns: 音源数
#n_iterations: 繰り返しステップ数
#return R 共分散行列(Nk,Ns,M,M) v 時間周波数分散(Nk,Ns,Lt),c_bar 音源分離信号(M,Ns,Nk,Lt), cost_buff コスト (T)
def execute_mm_lgm_dereverb(x,x_bar,Ns=2,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
Lh=np.shape(x_bar)[0]
x_bar=np.reshape(x_bar,[Lh*M,Nk,Lt])
#Rとvを初期化する
mask=np.random.uniform(size=Nk*Ns*Lt)
mask=np.reshape(mask,(Nk,Ns,Lt))
R=np.einsum("kst,mkt,nkt->kstmn",mask,x,np.conjugate(x))
R=np.average(R,axis=2)
v=np.random.uniform(size=Nk*Ns*Lt)
v=np.reshape(v,(Nk,Ns,Lt))
#共分散行列を計算
x_bar_x_bar_H=np.einsum('ikt,jkt->ktij',x_bar,np.conjugate(x_bar))
#相関行列を計算
x_bar_x_H=np.einsum('ikt,mkt->ktim',x_bar,np.conjugate(x))
cost_buff=[]
for t in range(n_iterations):
#入力信号の共分散行列を求める
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V=V+np.eye(M,M)*1.e-8
V_inverse=np.linalg.inv(V)
#残響除去フィルタを求める
x_barx_H_V_inv=np.einsum("ktim,ktmn->kin",x_bar_x_H,V_inverse)
vec_x_bar_x_HV_inv=np.reshape(np.transpose(x_barx_H_V_inv,[0,2,1]),(Nk,Lh*M*M))
#多次元配列対応版のクロネッカー積
V_inverse_x_x_H=batch_kron(np.transpose(V_inverse,(0,1,3,2)),x_bar_x_bar_H)
#vecHを求める
vec_h=np.einsum("kmr,kr->km",np.linalg.inv(np.sum(V_inverse_x_x_H,axis=1)), vec_x_bar_x_HV_inv)
#行列に戻す
h=np.transpose(np.reshape(vec_h,(Nk,M,Lh*M)),(0,2,1))
#残響除去を行う
x_reverb=np.einsum('kjm,jkt->mkt',np.conjugate(h),x_bar)
x_dereverb=x-x_reverb
#コスト計算
cost=np.sum(np.einsum("mkt,ktmn,nkt->kt",np.conjugate(x_dereverb),V_inverse,x_dereverb) +np.log(np.abs(np.linalg.det(V))))
cost/=np.float(Lt)
cost=np.real(cost)
cost_buff.append(cost)
#print(t,cost)
#パラメータを更新
#Rの更新
V_inverseX=np.einsum('ktmn,nkt->ktm',V_inverse,x_dereverb)
V_inverseXV_inverseX=np.einsum('ktm,ktn->ktmn',V_inverseX,np.conjugate(V_inverseX))
A=np.einsum('kst,ktmn->ksmn',v,V_inverse)
B=np.einsum('kst,ktmn->ksmn',v,V_inverseXV_inverseX)
RBR=np.einsum('ksmn,ksni,ksij->ksmj',R,B,R)
invA=np.linalg.pinv(A)
A_RBR=np.matmul(A,RBR)
R=np.concatenate([np.concatenate([np.matmul(invA[k,s,...],scipy.linalg.sqrtm(A_RBR[k,s,...]))[None,None,...] for k in range(Nk)],axis=0) for s in range(Ns)],axis=1)
R=(R+np.transpose(np.conjugate(R),[0,1,3,2]))/(2.0+0.0j)
#vの更新
v=v*np.sqrt(np.einsum('ktm,ktn,ksnm->kst',V_inverseX,np.conjugate(V_inverseX),R)/np.maximum(np.einsum('ktmn,ksnm->kst',V_inverse,R) ,1.e-18))
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V_inverse=np.linalg.pinv(V)
Wmwf=np.einsum("kstmi,ktin->kstmn",vR,V_inverse)
#音源分離信号を得る
c_bar=np.einsum('kstmn,nkt->mskt',Wmwf,x_dereverb)
return(R,v,c_bar,cost_buff)
#周波数間の振幅相関に基づくパーミュテーション解法
#s_hat: M,Nk,Lt
#return permutation_index_result:周波数毎のパーミュテーション解
def solver_inter_frequency_permutation(s_hat):
n_sources=np.shape(s_hat)[0]
n_freqs=np.shape(s_hat)[1]
n_frames=np.shape(s_hat)[2]
s_hat_abs=np.abs(s_hat)
norm_amp=np.sqrt(np.sum(np.square(s_hat_abs),axis=0,keepdims=True))
s_hat_abs=s_hat_abs/np.maximum(norm_amp,1.e-18)
spectral_similarity=np.einsum('mkt,nkt->k',s_hat_abs,s_hat_abs)
frequency_order=np.argsort(spectral_similarity)
#音源間の相関が最も低い周波数からパーミュテーションを解く
is_first=True
permutations=list(itertools.permutations(range(n_sources)))
permutation_index_result={}
for freq in frequency_order:
if is_first==True:
is_first=False
#初期値を設定する
accumurate_s_abs=s_hat_abs[:,frequency_order[0],:]
permutation_index_result[freq]=range(n_sources)
else:
max_correlation=0
max_correlation_perm=None
for perm in permutations:
s_hat_abs_temp=s_hat_abs[list(perm),freq,:]
correlation=np.sum(accumurate_s_abs*s_hat_abs_temp)
if max_correlation_perm is None:
max_correlation_perm=list(perm)
max_correlation=correlation
elif max_correlation < correlation:
max_correlation=correlation
max_correlation_perm=list(perm)
permutation_index_result[freq]=max_correlation_perm
accumurate_s_abs+=s_hat_abs[max_correlation_perm,freq,:]
return(permutation_index_result)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#SNRをはかる
#desired: 目的音、Lt
#out: 雑音除去後の信号 Lt
def calculate_snr(desired,out):
wave_length=np.minimum(np.shape(desired)[0],np.shape(out)[0])
#消し残った雑音
desired=desired[:wave_length]
out=out[:wave_length]
noise=desired-out
snr=10.*np.log10(np.sum(np.square(desired))/np.sum(np.square(noise)))
return(snr)
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#シミュレーションで用いる音源数
n_sim_sources=2
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#フレームシフト
Nshift=int(N/4)
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=90.
#方位角の閾値
azimuth_th=30.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_directions=np.array(
[[np.pi/2., theta/180.*np.pi] for theta in np.arange(180,361,180)
] )
distance=0.01
mic_alignments=np.zeros((3, mic_directions.shape[0]), dtype=mic_directions.dtype)
mic_alignments[0, :] = np.cos(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[1, :] = np.sin(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[2, :] = np.cos(mic_directions[:, 0])
mic_alignments *= distance
#マイクロホン数
n_channels=np.shape(mic_alignments)[1]
#マイクロホンアレイの座標
R=mic_alignments+mic_array_loc[:,None]
is_use_reverb=True
if is_use_reverb==False:
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_left = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_right = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
else:
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
room_no_noise_left = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_right = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise_left.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise_right.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., np.pi],
[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sim_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
if s==0:
room_no_noise_left.add_source(source_locations[:, s], signal=clean_data[s])
if s==1:
room_no_noise_right.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
room_no_noise_left.simulate(snr=90)
room_no_noise_right.simulate(snr=90)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
multi_conv_data_left_no_noise=room_no_noise_left.mic_array.signals
multi_conv_data_right_no_noise=room_no_noise_right.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_left_no_noise[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_left_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_right_no_noise[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_right_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_in_left.wav",sample_rate)
write_file_from_time_signal(multi_conv_data[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_in_right.wav",sample_rate)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
#ICAの繰り返し回数
n_ica_iterations=50
#残響除去のパラメータ
D=2
Lh=5
#過去のマイクロホン入力信号
x_bar=make_x_bar(stft_data,D,Lh)
#処理するフレーム数
Lt=np.shape(stft_data)[-1]
#MM法に基づくLGM+Dereverb実行コード
Rlgm_mm_dereverb,vlgm_mm_dereverb,y_lgm_mm_dereverb,cost_buff_lgm_mm_dereverb=execute_mm_lgm_dereverb(stft_data,x_bar,Ns=n_sources,n_iterations=n_ica_iterations)
permutation_index_result=solver_inter_frequency_permutation(y_lgm_mm_dereverb[0,...])
#パーミュテーションを解く
for k in range(Nk):
y_lgm_mm_dereverb[:,:,k,:]=y_lgm_mm_dereverb[:,permutation_index_result[k],k,:]
#MM法に基づくLGM実行コード
Rlgm_mm,vlgm_mm,y_lgm_mm,cost_buff_lgm_mm=execute_mm_lgm(stft_data,Ns=n_sources,n_iterations=n_ica_iterations)
permutation_index_result=solver_inter_frequency_permutation(y_lgm_mm[0,...])
for k in range(Nk):
y_lgm_mm[:,:,k,:]=y_lgm_mm[:,permutation_index_result[k],k,:]
t,y_lgm_mm=sp.istft(y_lgm_mm[0,...],fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
t,y_lgm_mm_dereverb=sp.istft(y_lgm_mm_dereverb[0,...],fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
snr_pre=calculate_snr(multi_conv_data_left_no_noise[0,...],multi_conv_data[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],multi_conv_data[0,...])
snr_pre/=2.
snr_lgm_mm_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_mm[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_mm[1,...])
snr_lgm_mm_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_mm[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_mm[0,...])
snr_lgm_mm_post=np.maximum(snr_lgm_mm_post1,snr_lgm_mm_post2)
snr_lgm_mm_post/=2.
snr_lgm_mm_dereverb_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_mm_dereverb[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_mm_dereverb[1,...])
snr_lgm_mm_dereverb_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_mm_dereverb[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_mm_dereverb[0,...])
snr_lgm_mm_dereverb_post=np.maximum(snr_lgm_mm_dereverb_post1,snr_lgm_mm_dereverb_post2)
snr_lgm_mm_dereverb_post/=2.
write_file_from_time_signal(y_lgm_mm[0,...]*np.iinfo(np.int16).max/20.,"./lgm_mm_1.wav",sample_rate)
write_file_from_time_signal(y_lgm_mm[1,...]*np.iinfo(np.int16).max/20.,"./lgm_mm_2.wav",sample_rate)
write_file_from_time_signal(y_lgm_mm_dereverb[0,...]*np.iinfo(np.int16).max/20.,"./lgm_mm_dereverb_1.wav",sample_rate)
write_file_from_time_signal(y_lgm_mm_dereverb[1,...]*np.iinfo(np.int16).max/20.,"./lgm_mm_dereverb_2.wav",sample_rate)
print("method: ", "LGM-MM","LGM-Dereverb-MM")
print("Δsnr [dB]: {:.2f} {:.2f}".format(snr_lgm_mm_post-snr_pre,snr_lgm_mm_dereverb_post-snr_pre))
#コストの値を表示
#for t in range(n_ica_iterations):
# print(t,cost_buff_lgm_mm[t],cost_buff_lgm_mm_dereverb[t])
================================================
FILE: section10/sample_code_c10_2.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
#順列計算に使用
import itertools
#A: ...mn
#B: ...ij
#AとBの最後の二軸以外の次元は一致していることを前提とする
def batch_kron(A,B):
if np.shape(A)[:-2]!=np.shape(B)[:-2]:
print("error")
return None
else:
return(np.reshape(np.einsum("...mn,...ij->...minj",A,B),np.shape(A)[:-2]+(np.shape(A)[-2]*np.shape(B)[-2],np.shape(A)[-1]*np.shape(B)[-1])))
#x:入力信号( M, Nk, Lt)
#D:遅延フレーム数
#Lh:残響除去フィルタのタップ長
#return x_bar: 過去のマイク入力信号(Lh,M,Nk,Lt)
def make_x_bar(x,D,Lh):
#フレーム数を取得
Lt=np.shape(x)[2]
#過去のマイク入力信号の配列を準備
x_bar=np.zeros(shape=(Lh,)+np.shape(x),dtype=np.complex)
for tau in range(Lh):
x_bar[tau,...,tau+D:]=x[:,:,:-(tau+D)]
return(x_bar)
#コントラスト関数の微分(球対称多次元ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def phi_multivariate_laplacian(s_hat):
power=np.square(np.abs(s_hat))
norm=np.sqrt(np.sum(power,axis=1,keepdims=True))
phi=s_hat/np.maximum(norm,1.e-18)
return(phi)
#コントラスト関数の微分(球対称ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def phi_laplacian(s_hat):
norm=np.abs(s_hat)
phi=s_hat/np.maximum(norm,1.e-18)
return(phi)
#コントラスト関数(球対称ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def contrast_laplacian(s_hat):
norm=2.*np.abs(s_hat)
return(norm)
#コントラスト関数(球対称多次元ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def contrast_multivariate_laplacian(s_hat):
power=np.square(np.abs(s_hat))
norm=2.*np.sqrt(np.sum(power,axis=1,keepdims=True))
return(norm)
#IP法による分離フィルタ更新
#x:入力信号( M, Nk, Lt)
#W: 分離フィルタ(Nk,M,M)
#a: アクティビティ(B,M,Lt)
#b: 基底(Nk,M,B)
#n_iterations: 繰り返しステップ数
#return W 分離フィルタ(Nk,M,M) s_hat 出力信号(M,Nk, Lt),cost_buff コスト (T)
def execute_ip_time_varying_gaussian_ilrma(x,W,a,b,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
cost_buff=[]
for t in range(n_iterations):
#音源分離信号を得る
s_hat=np.einsum('kmn,nkt->mkt',W,x)
s_power=np.square(np.abs(s_hat))
#時間周波数分散を更新
v=np.einsum("bst,ksb->skt",a,b)
#アクティビティの更新
a=a*np.sqrt(np.einsum("ksb,skt->bst",b,s_power/np.maximum(v,1.e-18)**2)/np.einsum("ksb,skt->bst",b,1./np.maximum(v,1.e-18)))
#基底の更新
b=b*np.sqrt(np.einsum("bst,skt->ksb",a,s_power /np.maximum(v,1.e-18)**2) /np.einsum("bst,skt->ksb",a,1./np.maximum(v,1.e-18)))
#時間周波数分散を再度更新
v=np.einsum("bst,ksb->skt",a,b)
#コスト計算
cost=np.sum(np.mean(s_power/np.maximum(v,1.e-18)+np.log(v),axis=-1)) -np.sum(2.*np.log(np.abs(np.linalg.det(W)) ))
cost_buff.append(cost)
#IP法による更新
Q=np.einsum('skt,mkt,nkt->tksmn',1./np.maximum(v,1.e-18),x,np.conjugate(x))
Q=np.average(Q,axis=0)
for source_index in range(M):
WQ=np.einsum('kmi,kin->kmn',W,Q[:,source_index,:,:])
invWQ=np.linalg.pinv(WQ)
W[:,source_index,:]=np.conjugate(invWQ[:,:,source_index])
wVw=np.einsum('km,kmn,kn->k',W[:,source_index,:],Q[:,source_index,:,:],np.conjugate(W[:,source_index,:]))
wVw=np.sqrt(np.abs(wVw))
W[:,source_index,:]=W[:,source_index,:]/np.maximum(wVw[:,None],1.e-18)
s_hat=np.einsum('kmn,nkt->mkt',W,x)
return(W,s_hat,cost_buff)
#IP法による分離フィルタ更新
#x:入力信号( M, Nk, Lt)
#x_bar:過去のマイク入力信号(Lh,M, Nk, Lt)
#P: 音源分離・残響除去フィルタ(Nk,M,(Lh+1)*M)
#a: アクティビティ(B,M,Lt)
#b: 基底(Nk,M,B)
#n_iterations: 繰り返しステップ数
#return W 分離フィルタ(Nk,M,M) s_hat 出力信号(M,Nk, Lt),cost_buff コスト (T)
def execute_ip_time_varying_gaussian_ilrma_t(x,x_bar,P,a,b,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
Lh=np.shape(x_bar)[0]
x_bar=np.reshape(x_bar,[Lh*M,Nk,Lt])
x_hat=np.concatenate((x,x_bar),axis=0)
#共分散行列を計算
x_hat_x_hat_H=np.einsum('ikt,jkt->ktij',x_hat,np.conjugate(x_hat))
cost_buff=[]
for t in range(n_iterations):
#時間周波数分散を更新
v=np.einsum("bst,ksb->skt",a,b)
#音源分離と残響除去を行う
s_hat=np.einsum('kmj,jkt->mkt',P,x_hat)
s_power=np.square(np.abs(s_hat))
#アクティビティの更新
a=a*np.sqrt(np.einsum("ksb,skt->bst",b,s_power/np.maximum(v,1.e-18)**2)/np.einsum("ksb,skt->bst",b,1./np.maximum(v,1.e-18)))
#基底の更新
b=b*np.sqrt(np.einsum("bst,skt->ksb",a,s_power /np.maximum(v,1.e-18)**2) /np.einsum("bst,skt->ksb",a,1./np.maximum(v,1.e-18)))
#時間周波数分散を再度更新
v=np.einsum("bst,ksb->skt",a,b)
#共分散行列を算出
Q=np.einsum("skt,ktij->tksij",1./np.maximum(v,1.e-18),x_hat_x_hat_H)
Q=np.average(Q,axis=0)
Q_inverse=np.linalg.pinv(Q)
for source_index in range(M):
P0=P[:,:,:M]
P0_inverse=np.linalg.pinv(P0)
#ステアリングベクトル
b_steering=P0_inverse[:,:,source_index]
b_h_Q_inverse_b=np.einsum("km,kmn,kn->k",np.conjugate(b_steering),Q_inverse[:,source_index,:M,:M],b_steering)
Q_inverse_b=np.einsum("kmn,kn->km",Q_inverse[:,source_index,:,:M],b_steering)
p=np.einsum("km,k->km",Q_inverse_b,1./np.sqrt(np.maximum(np.abs(b_h_Q_inverse_b),1.e-18)))
P[:,source_index,:]=np.conjugate(p)
#コスト計算
cost=np.sum(np.mean(s_power/np.maximum(v,1.e-18)+np.log(v),axis=-1)) -np.sum(2.*np.log(np.abs(np.linalg.det(P[:,:,:M])) ))
cost_buff.append(cost)
#print(t,cost)
s_hat=np.einsum('kmj,jkt->mkt',P,x_hat)
W=P[:,:,:M]
return(W,s_hat,cost_buff)
#IP法による分離フィルタ更新
#x:入力信号( M, Nk, Lt)
#x_bar:過去のマイク入力信号(Lh,M, Nk, Lt)
#W: 分離フィルタ(Nk,M,M)
#a: アクティビティ(B,M,Lt)
#b: 基底(Nk,M,B)
#n_iterations: 繰り返しステップ数
#return W 分離フィルタ(Nk,M,M) s_hat 出力信号(M,Nk, Lt),cost_buff コスト (T)
def execute_ip_time_varying_gaussian_ilrma_dereverb(x,x_bar,W,a,b,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
Lh=np.shape(x_bar)[0]
x_bar=np.reshape(x_bar,[Lh*M,Nk,Lt])
#共分散行列を計算
x_bar_x_bar_H=np.einsum('ikt,jkt->ktij',x_bar,np.conjugate(x_bar))
#相関行列を計算
x_bar_x_H=np.einsum('ikt,mkt->ktim',x_bar,np.conjugate(x))
cost_buff=[]
for t in range(n_iterations):
#時間周波数分散を更新
v=np.einsum("bst,ksb->skt",a,b)
#入力信号の共分散行列を求める
V_inverse=np.einsum("skt,ksm,ksn->ktmn",1./np.maximum(v,1.e-18),np.conjugate(W),W)
#残響除去フィルタを求める
x_barx_H_V_inv=np.einsum("ktim,ktmn->kin",x_bar_x_H,V_inverse)
vec_x_bar_x_HV_inv=np.reshape(np.transpose(x_barx_H_V_inv,[0,2,1]),(Nk,Lh*M*M))
#多次元配列対応版のクロネッカー積
V_inverse_x_x_H=batch_kron(np.transpose(V_inverse,(0,1,3,2)),x_bar_x_bar_H)
#vecHを求める
vec_h=np.einsum("kmr,kr->km",np.linalg.inv(np.sum(V_inverse_x_x_H,axis=1)), vec_x_bar_x_HV_inv)
#行列に戻す
h=np.transpose(np.reshape(vec_h,(Nk,M,Lh*M)),(0,2,1))
#残響除去を行う
x_reverb=np.einsum('kjm,jkt->mkt',np.conjugate(h),x_bar)
x_dereverb=x-x_reverb
#音源分離信号を得る
s_hat=np.einsum('kmn,nkt->mkt',W,x_dereverb)
s_power=np.square(np.abs(s_hat))
#アクティビティの更新
a=a*np.sqrt(np.einsum("ksb,skt->bst",b,s_power/np.maximum(v,1.e-18)**2)/np.einsum("ksb,skt->bst",b,1./np.maximum(v,1.e-18)))
#基底の更新
b=b*np.sqrt(np.einsum("bst,skt->ksb",a,s_power /np.maximum(v,1.e-18)**2) /np.einsum("bst,skt->ksb",a,1./np.maximum(v,1.e-18)))
#時間周波数分散を再度更新
v=np.einsum("bst,ksb->skt",a,b)
#コスト計算
cost=np.sum(np.mean(s_power/np.maximum(v,1.e-18)+np.log(v),axis=-1)) -np.sum(2.*np.log(np.abs(np.linalg.det(W)) ))
cost_buff.append(cost)
#print(t,cost)
#IP法による更新
Q=np.einsum('skt,mkt,nkt->tksmn',1./np.maximum(v,1.e-18),x_dereverb,np.conjugate(x_dereverb))
Q=np.average(Q,axis=0)
for source_index in range(M):
WQ=np.einsum('kmi,kin->kmn',W,Q[:,source_index,:,:])
invWQ=np.linalg.pinv(WQ)
W[:,source_index,:]=np.conjugate(invWQ[:,:,source_index])
wVw=np.einsum('km,kmn,kn->k',W[:,source_index,:],Q[:,source_index,:,:],np.conjugate(W[:,source_index,:]))
wVw=np.sqrt(np.abs(wVw))
W[:,source_index,:]=W[:,source_index,:]/np.maximum(wVw[:,None],1.e-18)
s_hat=np.einsum('kmn,nkt->mkt',W,x_dereverb)
return(W,s_hat,cost_buff)
#プロジェクションバックで最終的な出力信号を求める
#s_hat: M,Nk,Lt
#W: 分離フィルタ(Nk,M,M)
#retunr c_hat: マイクロホン位置での分離結果(M,M,Nk,Lt)
def projection_back(s_hat,W):
#ステアリングベクトルを推定
A=np.linalg.pinv(W)
c_hat=np.einsum('kmi,ikt->mikt',A,s_hat)
return(c_hat)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#SNRをはかる
#desired: 目的音、Lt
#out: 雑音除去後の信号 Lt
def calculate_snr(desired,out):
wave_length=np.minimum(np.shape(desired)[0],np.shape(out)[0])
#消し残った雑音
desired=desired[:wave_length]
out=out[:wave_length]
noise=desired-out
snr=10.*np.log10(np.sum(np.square(desired))/np.sum(np.square(noise)))
return(snr)
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#シミュレーションで用いる音源数
n_sim_sources=2
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#フレームシフト
Nshift=int(N/4)
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=90.
#方位角の閾値
azimuth_th=30.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_directions=np.array(
[[np.pi/2., theta/180.*np.pi] for theta in np.arange(180,361,180)
] )
distance=0.01
mic_alignments=np.zeros((3, mic_directions.shape[0]), dtype=mic_directions.dtype)
mic_alignments[0, :] = np.cos(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[1, :] = np.sin(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[2, :] = np.cos(mic_directions[:, 0])
mic_alignments *= distance
#マイクロホン数
n_channels=np.shape(mic_alignments)[1]
#マイクロホンアレイの座標
R=mic_alignments+mic_array_loc[:,None]
is_use_reverb=True
if is_use_reverb==False:
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_left = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_right = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
else:
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
room_no_noise_left = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_right = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise_left.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise_right.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., np.pi],
[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sim_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
if s==0:
room_no_noise_left.add_source(source_locations[:, s], signal=clean_data[s])
if s==1:
room_no_noise_right.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
room_no_noise_left.simulate(snr=90)
room_no_noise_right.simulate(snr=90)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
multi_conv_data_left_no_noise=room_no_noise_left.mic_array.signals
multi_conv_data_right_no_noise=room_no_noise_right.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_left_no_noise[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_left_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_right_no_noise[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_right_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_in_left.wav",sample_rate)
write_file_from_time_signal(multi_conv_data[0,:]*np.iinfo(np.int16).max/20.,"./lgm_dereverb_in_right.wav",sample_rate)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
#ICAの繰り返し回数
n_ica_iterations=50
#残響除去のパラメータ
D=2
Lh=5
#過去のマイクロホン入力信号
x_bar=make_x_bar(stft_data,D,Lh)
#ILRMAの基底数
n_basis=2
#処理するフレーム数
Lt=np.shape(stft_data)[-1]
#分離フィルタを初期化
Wilrma=np.zeros(shape=(Nk,n_sources,n_sources),dtype=np.complex)
Pilrma_t=np.zeros(shape=(Nk,n_sources,(Lh+1)*n_sources),dtype=np.complex)
Wilrma=Wilrma+np.eye(n_sources)[None,...]
Wilrma_ip=Wilrma.copy()
for tau in range(0,Lh+1):
Pilrma_t[:,:,tau*n_sources:(tau+1)*n_sources]=Wilrma.copy()
#ILRMA用
b=np.ones(shape=(Nk,n_sources,n_basis))
a=np.random.uniform(size=(n_basis*n_sources*Lt))
a=np.reshape(a,(n_basis,n_sources,Lt))
#ILRMA-T実行
Wilrma_t,s_ilrma_t,cost_buff_ilrma_t=execute_ip_time_varying_gaussian_ilrma_t(stft_data,x_bar,Pilrma_t,a.copy(),b.copy(),n_iterations=n_ica_iterations)
y_ilrma_t=projection_back(s_ilrma_t,Wilrma_t)
#ILRMA+Dereverb実行 (IP法ベース)
Wilrma_dereverb_ip,s_ilrma_dereverb_ip,cost_buff_ilrma_dereverb_ip=execute_ip_time_varying_gaussian_ilrma_dereverb(stft_data,x_bar,Wilrma_ip.copy(),a.copy(),b.copy(),n_iterations=n_ica_iterations)
y_ilrma_dereverb_ip=projection_back(s_ilrma_dereverb_ip,Wilrma_dereverb_ip)
#ILRMA実行 (IP法ベース)
Wilrma_ip,s_ilrma_ip,cost_buff_ilrma_ip=execute_ip_time_varying_gaussian_ilrma(stft_data,Wilrma_ip,a.copy(),b.copy(),n_iterations=n_ica_iterations)
y_ilrma_ip=projection_back(s_ilrma_ip,Wilrma_ip)
t,y_ilrma_ip=sp.istft(y_ilrma_ip[0,...],fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
t,y_ilrma_t=sp.istft(y_ilrma_t[0,...],fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
t,y_ilrma_dereverb_ip=sp.istft(y_ilrma_dereverb_ip[0,...],fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
snr_pre=calculate_snr(multi_conv_data_left_no_noise[0,...],multi_conv_data[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],multi_conv_data[0,...])
snr_pre/=2.
snr_ilrma_t_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_t[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_t[1,...])
snr_ilrma_t_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_t[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_t[0,...])
snr_ilrma_t_post=np.maximum(snr_ilrma_t_post1,snr_ilrma_t_post2)
snr_ilrma_t_post/=2.
snr_ilrma_ip_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_ip[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_ip[1,...])
snr_ilrma_ip_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_ip[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_ip[0,...])
snr_ilrma_ip_post=np.maximum(snr_ilrma_ip_post1,snr_ilrma_ip_post2)
snr_ilrma_ip_post/=2.
snr_ilrma_dereverb_ip_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_dereverb_ip[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_dereverb_ip[1,...])
snr_ilrma_dereverb_ip_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_dereverb_ip[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_dereverb_ip[0,...])
snr_ilrma_dereverb_ip_post=np.maximum(snr_ilrma_dereverb_ip_post1,snr_ilrma_dereverb_ip_post2)
snr_ilrma_dereverb_ip_post/=2.
write_file_from_time_signal(y_ilrma_ip[0,...]*np.iinfo(np.int16).max/20.,"./ilrma_ip_1.wav",sample_rate)
write_file_from_time_signal(y_ilrma_ip[1,...]*np.iinfo(np.int16).max/20.,"./ilrma_ip_2.wav",sample_rate)
write_file_from_time_signal(y_ilrma_dereverb_ip[0,...]*np.iinfo(np.int16).max/20.,"./ilrma_dereverb_ip_1.wav",sample_rate)
write_file_from_time_signal(y_ilrma_dereverb_ip[1,...]*np.iinfo(np.int16).max/20.,"./ilrma_dereverb_ip_2.wav",sample_rate)
write_file_from_time_signal(y_ilrma_t[0,...]*np.iinfo(np.int16).max/20.,"./ilrma_t_1.wav",sample_rate)
write_file_from_time_signal(y_ilrma_t[1,...]*np.iinfo(np.int16).max/20.,"./ilrma_t_2.wav",sample_rate)
print("method: ", "ILRMA", "ILRMA-Dereverb","ILRMA-T")
print("Δsnr [dB]: {:.2f} {:.2f} {:.2f}".format(snr_ilrma_ip_post-snr_pre,snr_ilrma_dereverb_ip_post-snr_pre,snr_ilrma_t_post-snr_pre))
#コストの値を表示
#for t in range(n_ica_iterations):
# print(t,cost_buff_ilrma_ip[t],cost_buff_ilrma_dereverb_ip[t], cost_buff_ilrma_t[t])
================================================
FILE: section10.md
================================================
## 第10章のサンプルコード
* [LGMに基づく音源分離と
残響除去の統合的最適化法](section10/sample_code_c10_1.py)
* [ILRMAに基づく音源分離と
残響除去の統合的最適化法](section10/sample_code_c10_2.py)
================================================
FILE: section11/sample_code_c11_1.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
#順列計算に使用
import itertools
import time
#コントラスト関数の微分(球対称多次元ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def phi_multivariate_laplacian(s_hat):
power=np.square(np.abs(s_hat))
norm=np.sqrt(np.sum(power,axis=1,keepdims=True))
phi=s_hat/np.maximum(norm,1.e-18)
return(phi)
#コントラスト関数の微分(球対称ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def phi_laplacian(s_hat):
norm=np.abs(s_hat)
phi=s_hat/np.maximum(norm,1.e-18)
return(phi)
#コントラスト関数(球対称ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def contrast_laplacian(s_hat):
norm=2.*np.abs(s_hat)
return(norm)
#コントラスト関数(球対称多次元ラプラス分布を仮定)
#s_hat: 分離信号(M, Nk, Lt)
def contrast_multivariate_laplacian(s_hat):
power=np.square(np.abs(s_hat))
norm=2.*np.sqrt(np.sum(power,axis=1,keepdims=True))
return(norm)
#ICAによる分離フィルタ更新
#x:入力信号( M, Nk, Lt)
#W: 分離フィルタ(Nk,M,M)
#mu: 更新係数
#n_ica_iterations: 繰り返しステップ数
#phi_func: コントラスト関数の微分を与える関数
#contrast_func: コントラスト関数
#is_use_non_holonomic: True (非ホロノミック拘束を用いる) False (用いない)
#return W 分離フィルタ(Nk,M,M) s_hat 出力信号(M,Nk, Lt),cost_buff ICAのコスト (T)
def execute_natural_gradient_ica(x,W,phi_func=phi_laplacian,contrast_func=contrast_laplacian,mu=1.0,n_ica_iterations=20,is_use_non_holonomic=True):
#マイクロホン数を取得する
M=np.shape(x)[0]
cost_buff=[]
for t in range(n_ica_iterations):
#音源分離信号を得る
s_hat=np.einsum('kmn,nkt->mkt',W,x)
#コントラスト関数を計算
G=contrast_func(s_hat)
#コスト計算
cost=np.sum(np.mean(G,axis=-1))-np.sum(2.*np.log(np.abs(np.linalg.det(W)) ))
cost_buff.append(cost)
#コンストラクト関数の微分を取得
phi=phi_func(s_hat)
phi_s=np.einsum('mkt,nkt->ktmn',phi,np.conjugate(s_hat))
phi_s=np.mean(phi_s,axis=1)
I=np.eye(M,M)
if is_use_non_holonomic==False:
deltaW=np.einsum('kmi,kin->kmn',I[None,...]-phi_s,W)
else:
mask=(np.ones((M,M))-I)[None,...]
deltaW=np.einsum('kmi,kin->kmn',np.multiply(mask,-phi_s),W)
#フィルタを更新する
W=W+mu*deltaW
#最後に出力信号を分離
s_hat=np.einsum('kmn,nkt->mkt',W,x)
return(W,s_hat,cost_buff)
#EM法によるLGMのパラメータ推定法
#x:入力信号( M, Nk, Lt)
#Ns: 音源数
#n_iterations: 繰り返しステップ数
#return R 共分散行列(Nk,Ns,M,M) v 時間周波数分散(Nk,Ns,Lt),c_bar 音源分離信号(M,Ns,Nk,Lt), cost_buff コスト (T)
def execute_em_lgm(x,Ns=2,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
#Rとvを初期化する
mask=np.random.uniform(size=Nk*Ns*Lt)
mask=np.reshape(mask,(Nk,Ns,Lt))
R=np.einsum("kst,mkt,nkt->kstmn",mask,x,np.conjugate(x))
R=np.average(R,axis=2)
v=np.random.uniform(size=Nk*Ns*Lt)
v=np.reshape(v,(Nk,Ns,Lt))
cost_buff=[]
for t in range(n_iterations):
#入力信号の共分散行列を求める
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V_inverse=np.linalg.pinv(V)
#コスト計算
cost=np.sum(np.einsum("mkt,ktmn,nkt->kt",np.conjugate(x),V_inverse,x) +np.log(np.abs(np.linalg.det(V))))
cost/=np.float(Lt)
cost=np.real(cost)
cost_buff.append(cost)
Wmwf=np.einsum("kstmi,ktin->kstmn",vR,V_inverse)
#事後確率計算に必要なパラメータを推定
c_bar=np.einsum('kstmn,nkt->kstm',Wmwf,x)
R_bar=np.einsum("kstmi,kstin->kstmn",-1.*Wmwf+np.eye(M),vR)
P_bar=R_bar+np.einsum("kstm,kstn->kstmn",c_bar,np.conjugate(c_bar))
#パラメータを更新
R=np.average(P_bar/np.maximum(v,1.e-18)[...,None,None],axis=2)
R_inverse=np.linalg.pinv(R)
v=np.einsum("ksmi,kstim->kst",R_inverse,P_bar)
v=v/np.float(M)
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V_inverse=np.linalg.pinv(V)
Wmwf=np.einsum("kstmi,ktin->kstmn",vR,V_inverse)
#音源分離信号を得る
c_bar=np.einsum('kstmn,nkt->mskt',Wmwf,x)
return(R,v,c_bar,cost_buff)
#IP法によるLGMのパラメータ推定法
#x:入力信号( M, Nk, Lt)
#Ns: 音源数
#n_iterations: 繰り返しステップ数
#return R 共分散行列(Nk,Ns,M,M) v 時間周波数分散(Nk,Ns,Lt),c_bar 音源分離信号(M,Ns,Nk,Lt), cost_buff コスト (T)
def execute_mm_lgm(x,Ns=2,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
#Rとvを初期化する
mask=np.random.uniform(size=Nk*Ns*Lt)
mask=np.reshape(mask,(Nk,Ns,Lt))
R=np.einsum("kst,mkt,nkt->kstmn",mask,x,np.conjugate(x))
R=np.average(R,axis=2)
v=np.random.uniform(size=Nk*Ns*Lt)
v=np.reshape(v,(Nk,Ns,Lt))
cost_buff=[]
for t in range(n_iterations):
#入力信号の共分散行列を求める
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V_inverse=np.linalg.pinv(V)
#コスト計算
cost=np.sum(np.einsum("mkt,ktmn,nkt->kt",np.conjugate(x),V_inverse,x) +np.log(np.abs(np.linalg.det(V))))
cost/=np.float(Lt)
cost=np.real(cost)
cost_buff.append(cost)
#パラメータを更新
#Rの更新
V_inverseX=np.einsum('ktmn,nkt->ktm',V_inverse,x)
V_inverseXV_inverseX=np.einsum('ktm,ktn->ktmn',V_inverseX,np.conjugate(V_inverseX))
A=np.einsum('kst,ktmn->ksmn',v,V_inverse)
B=np.einsum('kst,ktmn->ksmn',v,V_inverseXV_inverseX)
RBR=np.einsum('ksmn,ksni,ksij->ksmj',R,B,R)
invA=np.linalg.pinv(A)
A_RBR=np.matmul(A,RBR)
R=np.concatenate([np.concatenate([np.matmul(invA[k,s,...],scipy.linalg.sqrtm(A_RBR[k,s,...]))[None,None,...] for k in range(Nk)],axis=0) for s in range(Ns)],axis=1)
R=(R+np.transpose(np.conjugate(R),[0,1,3,2]))/(2.0+0.0j)
#vの更新
v=v*np.sqrt(np.einsum('ktm,ktn,ksnm->kst',V_inverseX,np.conjugate(V_inverseX),R)/np.maximum(np.einsum('ktmn,ksnm->kst',V_inverse,R) ,1.e-18))
vR=np.einsum("kst,ksmn->kstmn",v,R)
V=np.sum(vR,axis=1)
V_inverse=np.linalg.pinv(V)
Wmwf=np.einsum("kstmi,ktin->kstmn",vR,V_inverse)
#音源分離信号を得る
c_bar=np.einsum('kstmn,nkt->mskt',Wmwf,x)
return(R,v,c_bar,cost_buff)
#IP法による分離フィルタ更新
#x:入力信号( M, Nk, Lt)
#W: 分離フィルタ(Nk,M,M)
#n_iterations: 繰り返しステップ数
#return W 分離フィルタ(Nk,M,M) s_hat 出力信号(M,Nk, Lt),cost_buff コスト (T)
def execute_ip_multivariate_laplacian_iva(x,W,n_iterations=20):
#マイクロホン数を取得する
M=np.shape(x)[0]
cost_buff=[]
for t in range(n_iterations):
#音源分離信号を得る
s_hat=np.einsum('kmn,nkt->mkt',W,x)
#補助変数を更新する
v=np.sqrt(np.sum(np.square(np.abs(s_hat)),axis=1))
#コントラスト関数を計算
G=contrast_multivariate_laplacian(s_hat)
#コスト計算
cost=np.sum(np.mean(G,axis=-1))-np.sum(2.*np.log(np.abs(np.linalg.det(W)) ))
cost_buff.append(cost)
#IP法による更新
Q=np.einsum('st,mkt,nkt->tksmn',1./np.maximum(v,1.e-18),x,np.conjugate(x))
Q=np.average(Q,axis=0)
for source_index in range(M):
WQ=np.einsum('kmi,kin->kmn',W,Q[:,source_index,:,:])
invWQ=np.linalg.pinv(WQ)
W[:,source_index,:]=np.conjugate(invWQ[:,:,source_index])
wVw=np.einsum('km,kmn,kn->k',W[:,source_index,:],Q[:,source_index,:,:],np.conjugate(W[:,source_index,:]))
wVw=np.sqrt(np.abs(wVw))
W[:,source_index,:]=W[:,source_index,:]/np.maximum(wVw[:,None],1.e-18)
s_hat=np.einsum('kmn,nkt->mkt',W,x)
return(W,s_hat,cost_buff)
#IP法による分離フィルタ更新
#x:入力信号( M, Nk, Lt)
#W: 分離フィルタ(Nk,M,M)
#a: アクティビティ(B,M,Lt)
#b: 基底(Nk,M,B)
#n_iterations: 繰り返しステップ数
#return W 分離フィルタ(Nk,M,M) s_hat 出力信号(M,Nk, Lt),cost_buff コスト (T)
def execute_ip_time_varying_gaussian_ilrma(x,W,a,b,n_iterations=20):
#マイクロホン数・周波数・フレーム数を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
cost_buff=[]
for t in range(n_iterations):
#音源分離信号を得る
s_hat=np.einsum('kmn,nkt->mkt',W,x)
s_power=np.square(np.abs(s_hat))
#時間周波数分散を更新
v=np.einsum("bst,ksb->skt",a,b)
#アクティビティの更新
a=a*np.sqrt(np.einsum("ksb,skt->bst",b,s_power/np.maximum(v,1.e-18)**2)/np.einsum("ksb,skt->bst",b,1./np.maximum(v,1.e-18)))
#基底の更新
b=b*np.sqrt(np.einsum("bst,skt->ksb",a,s_power /np.maximum(v,1.e-18)**2) /np.einsum("bst,skt->ksb",a,1./np.maximum(v,1.e-18)))
#時間周波数分散を再度更新
v=np.einsum("bst,ksb->skt",a,b)
#コスト計算
cost=np.sum(np.mean(s_power/np.maximum(v,1.e-18)+np.log(v),axis=-1)) -np.sum(2.*np.log(np.abs(np.linalg.det(W)) ))
cost_buff.append(cost)
#IP法による更新
Q=np.einsum('skt,mkt,nkt->tksmn',1./np.maximum(v,1.e-18),x,np.conjugate(x))
Q=np.average(Q,axis=0)
for source_index in range(M):
WQ=np.einsum('kmi,kin->kmn',W,Q[:,source_index,:,:])
invWQ=np.linalg.pinv(WQ)
W[:,source_index,:]=np.conjugate(invWQ[:,:,source_index])
wVw=np.einsum('km,kmn,kn->k',W[:,source_index,:],Q[:,source_index,:,:],np.conjugate(W[:,source_index,:]))
wVw=np.sqrt(np.abs(wVw))
W[:,source_index,:]=W[:,source_index,:]/np.maximum(wVw[:,None],1.e-18)
s_hat=np.einsum('kmn,nkt->mkt',W,x)
return(W,s_hat,cost_buff)
#周波数間の振幅相関に基づくパーミュテーション解法
#s_hat: M,Nk,Lt
#return permutation_index_result:周波数毎のパーミュテーション解
def solver_inter_frequency_permutation(s_hat):
n_sources=np.shape(s_hat)[0]
n_freqs=np.shape(s_hat)[1]
n_frames=np.shape(s_hat)[2]
s_hat_abs=np.abs(s_hat)
norm_amp=np.sqrt(np.sum(np.square(s_hat_abs),axis=0,keepdims=True))
s_hat_abs=s_hat_abs/np.maximum(norm_amp,1.e-18)
spectral_similarity=np.einsum('mkt,nkt->k',s_hat_abs,s_hat_abs)
frequency_order=np.argsort(spectral_similarity)
#音源間の相関が最も低い周波数からパーミュテーションを解く
is_first=True
permutations=list(itertools.permutations(range(n_sources)))
permutation_index_result={}
for freq in frequency_order:
if is_first==True:
is_first=False
#初期値を設定する
accumurate_s_abs=s_hat_abs[:,frequency_order[0],:]
permutation_index_result[freq]=range(n_sources)
else:
max_correlation=0
max_correlation_perm=None
for perm in permutations:
s_hat_abs_temp=s_hat_abs[list(perm),freq,:]
correlation=np.sum(accumurate_s_abs*s_hat_abs_temp)
if max_correlation_perm is None:
max_correlation_perm=list(perm)
max_correlation=correlation
elif max_correlation < correlation:
max_correlation=correlation
max_correlation_perm=list(perm)
permutation_index_result[freq]=max_correlation_perm
accumurate_s_abs+=s_hat_abs[max_correlation_perm,freq,:]
return(permutation_index_result)
#プロジェクションバックで最終的な出力信号を求める
#s_hat: M,Nk,Lt
#W: 分離フィルタ(Nk,M,M)
#retunr c_hat: マイクロホン位置での分離結果(M,M,Nk,Lt)
def projection_back(s_hat,W):
#ステアリングベクトルを推定
A=np.linalg.pinv(W)
c_hat=np.einsum('kmi,ikt->mikt',A,s_hat)
return(c_hat)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#SNRをはかる
#desired: 目的音、Lt
#out: 雑音除去後の信号 Lt
def calculate_snr(desired,out):
wave_length=np.minimum(np.shape(desired)[0],np.shape(out)[0])
#消し残った雑音
desired=desired[:wave_length]
out=out[:wave_length]
noise=desired-out
snr=10.*np.log10(np.sum(np.square(desired))/np.sum(np.square(noise)))
return(snr)
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#シミュレーションで用いる音源数
n_sim_sources=2
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=90.
#方位角の閾値
azimuth_th=30.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_directions=np.array(
[[np.pi/2., theta/180.*np.pi] for theta in np.arange(180,361,180)
] )
distance=0.01
mic_alignments=np.zeros((3, mic_directions.shape[0]), dtype=mic_directions.dtype)
mic_alignments[0, :] = np.cos(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[1, :] = np.sin(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[2, :] = np.cos(mic_directions[:, 0])
mic_alignments *= distance
#マイクロホン数
n_channels=np.shape(mic_alignments)[1]
#マイクロホンアレイの座標
R=mic_alignments+mic_array_loc[:,None]
is_use_reverb=True
if is_use_reverb==False:
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_left = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
room_no_noise_right = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
else:
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
room_no_noise_left = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
room_no_noise_right = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise_left.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise_right.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., np.pi],
[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sim_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
if s==0:
room_no_noise_left.add_source(source_locations[:, s], signal=clean_data[s])
if s==1:
room_no_noise_right.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
room_no_noise_left.simulate(snr=90)
room_no_noise_right.simulate(snr=90)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
multi_conv_data_left_no_noise=room_no_noise_left.mic_array.signals
multi_conv_data_right_no_noise=room_no_noise_right.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_left_no_noise[0,:]*np.iinfo(np.int16).max/20.,"./ica_left_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_right_no_noise[0,:]*np.iinfo(np.int16).max/20.,"./ica_right_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,:]*np.iinfo(np.int16).max/20.,"./ica_in_left.wav",sample_rate)
write_file_from_time_signal(multi_conv_data[0,:]*np.iinfo(np.int16).max/20.,"./ica_in_right.wav",sample_rate)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#ICAの繰り返し回数
n_ica_iterations=50
#ILRMAの基底数
n_basis=2
#処理するフレーム数
Lt=np.shape(stft_data)[-1]
#ICAの分離フィルタを初期化
Wica=np.zeros(shape=(Nk,n_sources,n_sources),dtype=np.complex)
#Wica=np.random.normal(size=Nk*n_sources*n_sources)+1.j*np.random.normal(size=Nk*n_sources*n_sources)
#Wica=np.reshape(Wica,(Nk,n_sources,n_sources))
Wica=Wica+np.eye(n_sources)[None,...]
Wiva=Wica.copy()
Wiva_ip=Wica.copy()
Wilrma_ip=Wica.copy()
#ILRMA用
b=np.ones(shape=(Nk,n_sources,n_basis))
a=np.random.uniform(size=(n_basis*n_sources*Lt))
a=np.reshape(a,(n_basis,n_sources,Lt))
#Pyroomacousticsによる音源分離
#nframes, nfrequencies, nchannels
#入力信号のインデックスの順番を( M, Nk, Lt)から(Lt,Nk,M)に変換する
y_pa_auxiva=pa.bss.auxiva(np.transpose(stft_data,(2,1,0)),n_iter=n_ica_iterations)
y_pa_auxiva=np.transpose(y_pa_auxiva,(2,1,0))[None,...]
y_pa_ilrma=pa.bss.ilrma(np.transpose(stft_data,(2,1,0)),n_iter=n_ica_iterations)
y_pa_ilrma=np.transpose(y_pa_ilrma,(2,1,0))[None,...]
y_pa_fastmnmf=pa.bss.fastmnmf(np.transpose(stft_data,(2,1,0)),n_iter=n_ica_iterations,initialize_ilrma=True)
y_pa_fastmnmf=np.transpose(y_pa_fastmnmf,(2,1,0))[None,...]
start_time=time.time()
#自然勾配法に基づくIVA実行コード(引数に与える関数を変更するだけ)
Wiva,s_iva,cost_buff_iva=execute_natural_gradient_ica(stft_data,Wiva,phi_func=phi_multivariate_laplacian,contrast_func=contrast_multivariate_laplacian,mu=0.1,n_ica_iterations=n_ica_iterations,is_use_non_holonomic=False)
y_iva=projection_back(s_iva,Wiva)
iva_time=time.time()
#IP法に基づくIVA実行コード(引数に与える関数を変更するだけ)
Wilrma_ip,s_ilrma_ip,cost_buff_ilrma_ip=execute_ip_time_varying_gaussian_ilrma(stft_data,Wilrma_ip,a,b,n_iterations=n_ica_iterations)
y_ilrma_ip=projection_back(s_ilrma_ip,Wilrma_ip)
ilrma_ip_time=time.time()
#IP法に基づくIVA実行コード(引数に与える関数を変更するだけ)
Wiva_ip,s_iva_ip,cost_buff_iva_ip=execute_ip_multivariate_laplacian_iva(stft_data,Wiva_ip,n_iterations=n_ica_iterations)
y_iva_ip=projection_back(s_iva_ip,Wiva_ip)
iva_ip_time=time.time()
Wica,s_ica,cost_buff_ica=execute_natural_gradient_ica(stft_data,Wica,mu=0.1,n_ica_iterations=n_ica_iterations,is_use_non_holonomic=False)
permutation_index_result=solver_inter_frequency_permutation(s_ica)
y_ica=projection_back(s_ica,Wica)
#パーミュテーションを解く
for k in range(Nk):
y_ica[:,:,k,:]=y_ica[:,permutation_index_result[k],k,:]
ica_time=time.time()
#MM法に基づくLGM実行コード
Rlgm_mm,vlgm_mm,y_lgm_mm,cost_buff_lgm_mm=execute_mm_lgm(stft_data,Ns=n_sources,n_iterations=n_ica_iterations)
permutation_index_result=solver_inter_frequency_permutation(y_lgm_mm[0,...])
#パーミュテーションを解く
for k in range(Nk):
y_lgm_mm[:,:,k,:]=y_lgm_mm[:,permutation_index_result[k],k,:]
lgm_mm_time=time.time()
#EMアルゴリズムに基づくLGM実行コード
Rlgm_em,vlgm_em,y_lgm_em,cost_buff_lgm_em=execute_em_lgm(stft_data,Ns=n_sources,n_iterations=n_ica_iterations)
permutation_index_result=solver_inter_frequency_permutation(y_lgm_em[0,...])
#パーミュテーションを解く
for k in range(Nk):
y_lgm_em[:,:,k,:]=y_lgm_em[:,permutation_index_result[k],k,:]
lgm_em_time=time.time()
t,y_pa_auxiva=sp.istft(y_pa_auxiva[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_pa_ilrma=sp.istft(y_pa_ilrma[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_pa_fastmnmf=sp.istft(y_pa_fastmnmf[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_ica=sp.istft(y_ica[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_iva=sp.istft(y_iva[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_iva_ip=sp.istft(y_iva_ip[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_ilrma_ip=sp.istft(y_ilrma_ip[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_lgm_em=sp.istft(y_lgm_em[0,...],fs=sample_rate,window="hann",nperseg=N)
t,y_lgm_mm=sp.istft(y_lgm_mm[0,...],fs=sample_rate,window="hann",nperseg=N)
snr_pre=calculate_snr(multi_conv_data_left_no_noise[0,...],multi_conv_data[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],multi_conv_data[0,...])
snr_pre/=2.
snr_ica_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ica[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ica[1,...])
snr_ica_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ica[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ica[0,...])
snr_ica_post=np.maximum(snr_ica_post1,snr_ica_post2)
snr_ica_post/=2.
snr_pa_ilrma_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_pa_ilrma[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_pa_ilrma[1,...])
snr_pa_ilrma_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_pa_ilrma[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_pa_ilrma[0,...])
snr_pa_ilrma_post=np.maximum(snr_pa_ilrma_post1,snr_pa_ilrma_post2)
snr_pa_ilrma_post/=2.
snr_pa_fastmnmf_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_pa_fastmnmf[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_pa_fastmnmf[1,...])
snr_pa_fastmnmf_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_pa_fastmnmf[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_pa_fastmnmf[0,...])
snr_pa_fastmnmf_post=np.maximum(snr_pa_fastmnmf_post1,snr_pa_fastmnmf_post2)
snr_pa_fastmnmf_post/=2.
snr_pa_auxiva_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_pa_auxiva[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_pa_auxiva[1,...])
snr_pa_auxiva_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_pa_auxiva[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_pa_auxiva[0,...])
snr_pa_auxiva_post=np.maximum(snr_pa_auxiva_post1,snr_pa_auxiva_post2)
snr_pa_auxiva_post/=2.
snr_iva_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_iva[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_iva[1,...])
snr_iva_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_iva[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_iva[0,...])
snr_iva_post=np.maximum(snr_iva_post1,snr_iva_post2)
snr_iva_post/=2.
snr_iva_ip_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_iva_ip[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_iva_ip[1,...])
snr_iva_ip_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_iva_ip[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_iva_ip[0,...])
snr_iva_ip_post=np.maximum(snr_iva_ip_post1,snr_iva_ip_post2)
snr_iva_ip_post/=2.
snr_ilrma_ip_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_ip[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_ip[1,...])
snr_ilrma_ip_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_ilrma_ip[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_ilrma_ip[0,...])
snr_ilrma_ip_post=np.maximum(snr_ilrma_ip_post1,snr_ilrma_ip_post2)
snr_ilrma_ip_post/=2.
snr_lgm_mm_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_mm[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_mm[1,...])
snr_lgm_mm_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_mm[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_mm[0,...])
snr_lgm_mm_post=np.maximum(snr_lgm_mm_post1,snr_lgm_mm_post2)
snr_lgm_mm_post/=2.
snr_lgm_em_post1=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_em[0,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_em[1,...])
snr_lgm_em_post2=calculate_snr(multi_conv_data_left_no_noise[0,...],y_lgm_em[1,...])+calculate_snr(multi_conv_data_right_no_noise[0,...],y_lgm_em[0,...])
snr_lgm_em_post=np.maximum(snr_lgm_em_post1,snr_lgm_em_post2)
snr_lgm_em_post/=2.
write_file_from_time_signal(y_ica[0,...]*np.iinfo(np.int16).max/20.,"./ica_1.wav",sample_rate)
write_file_from_time_signal(y_ica[1,...]*np.iinfo(np.int16).max/20.,"./ica_2.wav",sample_rate)
write_file_from_time_signal(y_pa_auxiva[0,...]*np.iinfo(np.int16).max/20.,"./pa_auxiva_1.wav",sample_rate)
write_file_from_time_signal(y_pa_auxiva[1,...]*np.iinfo(np.int16).max/20.,"./pa_auxiva_2.wav",sample_rate)
write_file_from_time_signal(y_pa_ilrma[0,...]*np.iinfo(np.int16).max/20.,"./pa_ilrma_1.wav",sample_rate)
write_file_from_time_signal(y_pa_ilrma[1,...]*np.iinfo(np.int16).max/20.,"./pa_ilrma_2.wav",sample_rate)
write_file_from_time_signal(y_pa_fastmnmf[0,...]*np.iinfo(np.int16).max/20.,"./pa_fastmnmf_1.wav",sample_rate)
write_file_from_time_signal(y_pa_fastmnmf[1,...]*np.iinfo(np.int16).max/20.,"./pa_fastmnmf_2.wav",sample_rate)
write_file_from_time_signal(y_iva[0,...]*np.iinfo(np.int16).max/20.,"./iva_1.wav",sample_rate)
write_file_from_time_signal(y_iva[1,...]*np.iinfo(np.int16).max/20.,"./iva_2.wav",sample_rate)
write_file_from_time_signal(y_iva_ip[0,...]*np.iinfo(np.int16).max/20.,"./iva_ip_1.wav",sample_rate)
write_file_from_time_signal(y_iva_ip[1,...]*np.iinfo(np.int16).max/20.,"./iva_ip_2.wav",sample_rate)
write_file_from_time_signal(y_ilrma_ip[0,...]*np.iinfo(np.int16).max/20.,"./ilrma_ip_1.wav",sample_rate)
write_file_from_time_signal(y_ilrma_ip[1,...]*np.iinfo(np.int16).max/20.,"./ilrma_ip_2.wav",sample_rate)
write_file_from_time_signal(y_lgm_em[0,...]*np.iinfo(np.int16).max/20.,"./lgm_em_1.wav",sample_rate)
write_file_from_time_signal(y_lgm_em[1,...]*np.iinfo(np.int16).max/20.,"./lgm_em_2.wav",sample_rate)
write_file_from_time_signal(y_lgm_mm[0,...]*np.iinfo(np.int16).max/20.,"./lgm_mm_1.wav",sample_rate)
write_file_from_time_signal(y_lgm_mm[1,...]*np.iinfo(np.int16).max/20.,"./lgm_mm_2.wav",sample_rate)
print("method: ", "PA-AUXIVA","PA-ILRMA","PA-FASTMNMF","NG-ICA", "NG-IVA", "AuxIVA", "ILRMA","LGM-EM","LGM-MM")
print("処理時間[sec]: {:.2f} [sec] {:.2f} [sec] {:.2f} [sec] {:.2f} [sec] {:.2f} [sec] {:.2f} [sec]".format(ica_time-iva_ip_time,iva_ip_time-ilrma_ip_time,iva_time-start_time,ilrma_ip_time-iva_time,lgm_em_time-lgm_mm_time,lgm_mm_time-ica_time))
print("Δsnr [dB]: {:.2f} {:.2f} {:.2f} {:.2f} {:.2f} {:.2f} {:.2f} {:.2f} {:.2f}".format(snr_pa_auxiva_post-snr_pre,snr_pa_ilrma_post-snr_pre,snr_pa_fastmnmf_post-snr_pre,snr_ica_post-snr_pre,snr_iva_post-snr_pre,snr_iva_ip_post-snr_pre,snr_ilrma_ip_post-snr_pre,snr_lgm_em_post-snr_pre,snr_lgm_mm_post-snr_pre))
#コストの値を表示
#for t in range(n_ica_iterations):
# print(t,cost_buff_ica[t],cost_buff_iva[t],cost_buff_iva_ip[t],cost_buff_ilrma_ip[t],cost_buff_lgm_em[t],cost_buff_lgm_mm[t])
================================================
FILE: section11/sample_code_c11_2.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
import time
import nara_wpe.wpe as wpe
#x:入力信号( M, Nk, Lt)
#D:遅延フレーム数
#Lh:残響除去フィルタのタップ長
#return x_bar: 過去のマイク入力信号(Lh,M,Nk,Lt)
def make_x_bar(x,D,Lh):
#フレーム数を取得
Lt=np.shape(x)[2]
#過去のマイク入力信号の配列を準備
x_bar=np.zeros(shape=(Lh,)+np.shape(x),dtype=np.complex)
for tau in range(Lh):
x_bar[tau,...,tau+D:]=x[:,:,:-(tau+D)]
return(x_bar)
#最小二乗で除去
#x:入力信号( M, Nk, Lt)
#x_bar:過去のマイク入力信号(Lh,M, Nk, Lt)
#return x_dereverb:残響除去後の信号(Nk,Lt)
def dereverberation_ls(x,x_bar):
#マイクロホン数・周波数・フレーム数・タップ長を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
Lh=np.shape(x_bar)[0]
x_bar=np.reshape(x_bar,[Lh*M,Nk,Lt])
x_bar_x_bar_h=np.einsum('ikt,jkt->kij',x_bar,np.conjugate(x_bar))
#covariance_inverse=np.linalg.pinv(x_bar_x_bar_h)
correlation=np.einsum('ikt,kt->ki',x_bar,np.conjugate(x[0,...]))
filter=np.linalg.solve(x_bar_x_bar_h,correlation)
#filter=np.einsum('kij,kj->ki',covariance_inverse,correlation)
x_reverb=np.einsum('kj,jkt->kt',np.conjugate(filter),x_bar)
x_dereverb=x[0,...]-x_reverb
return(x_dereverb)
#WPEで残響を除去
#x:入力信号( M, Nk, Lt)
#x_bar:過去のマイク入力信号(Lh,M, Nk, Lt)
#return x_dereverb:残響除去後の信号(Nk,Lt)
def dereverberation_wpe(x,x_bar,wpe_iterations=10):
#マイクロホン数・周波数・フレーム数・タップ長を取得する
M=np.shape(x)[0]
Nk=np.shape(x)[1]
Lt=np.shape(x)[2]
Lh=np.shape(x_bar)[0]
#入力信号の形式を変更・変数を初期化
x_bar=np.reshape(x_bar,[Lh*M,Nk,Lt])
v=np.square(np.abs(x[0,...]))
cost_buff=[]
for t in range(wpe_iterations):
#共分散行列を計算
x_bar_x_bar_h=np.einsum('kt,ikt,jkt->kij',1./v,x_bar,np.conjugate(x_bar))
#相関ベクトルを計算
correlation=np.einsum('kt,ikt,kt->ki',1./v,x_bar,np.conjugate(x[0,...]))
#フィルタ算出
filter=np.linalg.solve(x_bar_x_bar_h,correlation)
#残響除去実施
x_reverb=np.einsum('kj,jkt->kt',np.conjugate(filter),x_bar)
x_dereverb=x[0,...]-x_reverb
#パラメータ更新
v=np.square(np.abs(x_dereverb))
v=np.maximum(v,1.e-8)
#コスト計算
cost=np.mean(np.log(v))
cost_buff.append(cost)
return(x_dereverb,cost_buff)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#SNRをはかる
#desired: 目的音、Lt
#out: 雑音除去後の信号 Lt
def calculate_snr(desired,out):
wave_length=np.minimum(np.shape(desired)[0],np.shape(out)[0])
#消し残った雑音
desired=desired[:wave_length]
out=out[:wave_length]
noise=desired-out
snr=10.*np.log10(np.sum(np.square(desired))/np.sum(np.square(noise)))
return(snr)
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#シミュレーションで用いる音源数
n_sim_sources=1
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#フレームシフト
Nshift=int(N/4)
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=90.
#方位角の閾値
azimuth_th=30.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_directions=np.array(
[[np.pi/2., theta/180.*np.pi] for theta in np.arange(180,361,180)
] )
distance=0.01
mic_alignments=np.zeros((3, mic_directions.shape[0]), dtype=mic_directions.dtype)
mic_alignments[0, :] = np.cos(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[1, :] = np.sin(mic_directions[:, 1]) * np.sin(mic_directions[:, 0])
mic_alignments[2, :] = np.cos(mic_directions[:, 0])
mic_alignments *= distance
#マイクロホン数
n_channels=np.shape(mic_alignments)[1]
#マイクロホンアレイの座標
R=mic_alignments+mic_array_loc[:,None]
is_use_reverb=True
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
room_no_reverb = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_reverb.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., np.pi]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sim_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
room_no_reverb.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
room_no_reverb.simulate(snr=90)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
multi_conv_data_no_reverb=room_no_reverb.mic_array.signals
wave_len=np.shape(multi_conv_data_no_reverb)[1]
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_no_reverb[0,:wave_len]*np.iinfo(np.int16).max/20.,"./dereverb_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,:wave_len]*np.iinfo(np.int16).max/20.,"./dereverb_in.wav",sample_rate)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
#WPEの繰り返し回数
n_wpe_iterations=20
#残響除去のパラメータ
D=2
Lh=5
#過去のマイクロホン入力信号
x_bar=make_x_bar(stft_data,D,Lh)
#WPEで残響除去
x_dereverb_wpe,cost_buff_wpe=dereverberation_wpe(stft_data,x_bar,n_wpe_iterations)
#nara WPEで残響除去
x_dereverb_nara_wpe=wpe.wpe(np.transpose(stft_data,(1,0,2)),taps=Lh,delay=D,iterations=n_wpe_iterations)
x_dereverb_nara_wpe=np.transpose(x_dereverb_nara_wpe,(1,0,2))[0,...]
#x:入力信号( M, Nk, Lt)
t,x_dereverb_wpe=sp.istft(x_dereverb_wpe,fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
t,x_dereverb_nara_wpe=sp.istft(x_dereverb_nara_wpe,fs=sample_rate,window="hann",nperseg=N,noverlap=N-Nshift)
snr_pre=calculate_snr(multi_conv_data_no_reverb[0,...],multi_conv_data[0,...])
snr_wpe_post=calculate_snr(multi_conv_data_no_reverb[0,...],x_dereverb_wpe)
snr_nara_wpe_post=calculate_snr(multi_conv_data_no_reverb[0,...],x_dereverb_nara_wpe)
write_file_from_time_signal(x_dereverb_wpe[:wave_len]*np.iinfo(np.int16).max/20.,"./dereverb_wpe_{}_{}.wav".format(Lh,D),sample_rate)
write_file_from_time_signal(x_dereverb_nara_wpe[:wave_len]*np.iinfo(np.int16).max/20.,"./dereverb_nara_wpe.wav",sample_rate)
print("method: ", "WPE","NARA-WPE")
print("Δsnr [dB]: {:.2f} {:.2f}".format(snr_wpe_post-snr_pre,snr_nara_wpe_post-snr_pre))
#コストの値を表示
#for t in range(n_wpe_iterations):
# print(t,cost_buff_wpe[t])
================================================
FILE: section11.md
================================================
## 第11章のサンプルコード
* [pyroomacousticsによる音源分離技術](section11/sample_code_c11_1.py)
* [NARA-WPEを用いた残響除去](section11/sample_code_c11_2.py)
================================================
FILE: section2/sample_code_c2_1.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#pyroomacousticsをインポート (ここではデータセットをダウンロードするために使用)
import pyroomacoustics as pa
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#CMU ARCTIC Corpusをカレントディレクトリにダウンロード
pa.datasets.CMUArcticCorpus(basedir="./CMU_ARCTIC",download=True,speaker=["aew","axb"])
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#ファイルの情報を出力する
print("サンプリング周波数[Hz]: ",wav.getframerate())
print("サンプルサイズ[Byte]: ", wav.getsampwidth())
print("サンプル数: ",wav.getnframes())
print("チャンネル数: ",wav.getnchannels())
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#waveファイルを閉じる
wav.close()
================================================
FILE: section2/sample_code_c2_10.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#scipyのsignalモジュールをインポート(stft等信号処理計算用)
import scipy.signal as sp
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#時間領域の波形に戻す
t,data_post=sp.istft(stft_data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#2バイトのデータに変換
data_post=data_post.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open("./istft_post_wave.wav", 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(wav.getframerate())
#データを書き込み
wave_out.writeframes(data_post)
#ファイルを閉じる
wave_out.close()
#waveファイルを閉じる
wav.close()
================================================
FILE: section2/sample_code_c2_11.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#scipyのsignalモジュールをインポート(stft等信号処理計算用)
import scipy.signal as sp
#sounddeviceモジュールをインポート
import sounddevice as sd
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#特定の周波数成分を消す(100番目の周波数よりも高い周波数成分を全て消す)
stft_data[100:,:]=0
#時間領域の波形に戻す
t,data_post=sp.istft(stft_data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#2バイトのデータに変換
data_post=data_post.astype(np.int16)
#dataを再生する
sd.play(data_post,wav.getframerate())
print("再生開始")
#再生が終わるまで待つ
status = sd.wait()
#waveファイルを閉じる
wav.close()
================================================
FILE: section2/sample_code_c2_12.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#scipyのsignalモジュールをインポート(stft等信号処理計算用)
import scipy.signal as sp
#sounddeviceモジュールをインポート
import sounddevice as sd
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#特定の周波数成分を消す(50番目の周波数よりも低い周波数成分を全て消す)
stft_data[:50,:]=0
#時間領域の波形に戻す
t,data_post=sp.istft(stft_data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#2バイトのデータに変換
data_post=data_post.astype(np.int16)
#dataを再生する
sd.play(data_post,wav.getframerate())
print("再生開始")
#再生が終わるまで待つ
status = sd.wait()
#waveファイルを閉じる
wav.close()
================================================
FILE: section2/sample_code_c2_13.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#scipyのsignalモジュールをインポート(stft等信号処理計算用)
import scipy.signal as sp
#sounddeviceモジュールをインポート
import sounddevice as sd
#乱数の種を設定
np.random.seed(0)
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#音声区間の長さを取る
n_speech=wav.getnframes()
#サンプリングレートを取る
sampling_rate=wav.getframerate()
#PCM形式の波形データを読み込み
speech_signal=wav.readframes(wav.getnframes())
#speech_signalを2バイトの数値列に変換
speech_signal=np.frombuffer(speech_signal, dtype=np.int16)
#音声データに白色雑音を混ぜる
#雑音だけの区間のサンプル数を設定
n_noise_only=40000
#全体の長さ
n_sample=n_noise_only+n_speech
#白色雑音を生成
wgn_signal=np.random.normal(scale=0.04,size=n_sample)
#2バイトのデータとして書き込むためにスケールを調整
wgn_signal=wgn_signal*np.iinfo(np.int16).max
#2バイトのデータに変換
wgn_signal=wgn_signal.astype(np.int16)
#白色雑音を混ぜる
mix_signal=wgn_signal
mix_signal[n_noise_only:]+=speech_signal
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(mix_signal,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#入力信号の振幅を取得
amp=np.abs(stft_data)
#入力信号の位相を取得
phase=stft_data/np.maximum(amp,1.e-20)
#雑音だけの区間のフレーム数
n_noise_only_frame=np.sum(t<(n_noise_only/sampling_rate))
#スペクトルサブトラクションのパラメータ
p=1.0
alpha=2.0
#雑音の振幅を推定
noise_amp=np.power(np.mean(np.power(amp,p)[:,:n_noise_only_frame],axis=1,keepdims=True),1./p)
#入力信号の振幅の1%を下回らないようにする
eps=0.01*np.power(amp,p)
#出力信号の振幅を計算する
processed_amp=np.power(np.maximum(np.power(amp,p)-alpha*np.power(noise_amp,p),eps), 1./p)
#出力信号の振幅に入力信号の位相をかける
processed_stft_data=processed_amp*phase
#時間領域の波形に戻す
t,processed_data_post=sp.istft(processed_stft_data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#2バイトのデータに変換
processed_data_post=processed_data_post.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open("./process_wave_ss.wav", 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(wav.getframerate())
#データを書き込み
wave_out.writeframes(processed_data_post)
#ファイルを閉じる
wave_out.close()
import matplotlib.pyplot as plt
#スペクトログラムをプロットする
fig=plt.figure(figsize=(10,4))
#スペクトログラムを表示する
spectrum, freqs, t, im=plt.specgram(processed_data_post,NFFT=512,noverlap=512/16*15,Fs=wav.getframerate(),cmap="gray")
#カラーバーを表示する
fig.colorbar(im).set_label('Intensity [dB]')
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Frequency [Hz]")
#音声ファイルを画像として保存
plt.savefig("./spectrogram_ss_result.png")
#画像を画面に表示
plt.show()
#雑音込みの入力信号も時間領域の波形に戻す
t,data_post=sp.istft(stft_data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#2バイトのデータに変換
data_post=data_post.astype(np.int16)
#スペクトログラムをプロットする
fig=plt.figure(figsize=(10,4))
#スペクトログラムを表示する
spectrum, freqs, t, im=plt.specgram(data_post,NFFT=512,noverlap=512/16*15,Fs=wav.getframerate(),cmap="gray")
#カラーバーを表示する
fig.colorbar(im).set_label('Intensity [dB]')
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Frequency [Hz]")
#音声ファイルを画像として保存
plt.savefig("./spectrogram_noisy.png")
#画像を画面に表示
plt.show()
#waveファイルに書き込む
wave_out = wave.open("./input_wave.wav", 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(wav.getframerate())
#データを書き込み
wave_out.writeframes(data_post)
#ファイルを閉じる
wave_out.close()
#waveファイルを閉じる
wav.close()
================================================
FILE: section2/sample_code_c2_14.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#scipyのsignalモジュールをインポート(stft等信号処理計算用)
import scipy.signal as sp
#sounddeviceモジュールをインポート
import sounddevice as sd
#乱数の種を設定
np.random.seed(0)
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#音声区間の長さを取る
n_speech=wav.getnframes()
#サンプリングレートを取る
sampling_rate=wav.getframerate()
#PCM形式の波形データを読み込み
speech_signal=wav.readframes(wav.getnframes())
#speech_signalを2バイトの数値列に変換
speech_signal=np.frombuffer(speech_signal, dtype=np.int16)
#音声データに白色雑音を混ぜる
#雑音だけの区間のサンプル数を設定
n_noise_only=40000
#全体の長さ
n_sample=n_noise_only+n_speech
#白色雑音を生成
wgn_signal=np.random.normal(scale=0.04,size=n_sample)
#2バイトのデータとして書き込むためにスケールを調整
wgn_signal=wgn_signal*np.iinfo(np.int16).max
#2バイトのデータに変換
wgn_signal=wgn_signal.astype(np.int16)
#白色雑音を混ぜる
mix_signal=wgn_signal
mix_signal[n_noise_only:]+=speech_signal
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(mix_signal,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#入力信号の振幅を取得
amp=np.abs(stft_data)
#入力信号のパワーを取得
input_power=np.power(amp,2.0)
#雑音だけの区間のフレーム数
n_noise_only_frame=np.sum(t<(n_noise_only/sampling_rate))
#ウィナーフィルタのパラメータ
alpha=1.0
mu=10
#雑音のパワーを推定
noise_power=np.mean(np.power(amp,2.0)[:,:n_noise_only_frame],axis=1,keepdims=True)
#入力信号の音量の1%を下回らないようにする
eps=0.01*input_power
#出力信号の振幅を計算する
processed_power=np.maximum(input_power-alpha*noise_power,eps)
#比率
wf_ratio= processed_power/(processed_power+mu*noise_power)
#出力信号の振幅に入力信号の位相をかける
processed_stft_data=wf_ratio*stft_data
#時間領域の波形に戻す
t,processed_data_post=sp.istft(processed_stft_data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#2バイトのデータに変換
processed_data_post=processed_data_post.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open("./process_wave_wf.wav", 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(wav.getframerate())
#データを書き込み
wave_out.writeframes(processed_data_post)
#ファイルを閉じる
wave_out.close()
import matplotlib.pyplot as plt
#スペクトログラムをプロットする
fig=plt.figure(figsize=(10,4))
#スペクトログラムを表示する
spectrum, freqs, t, im=plt.specgram(processed_data_post,NFFT=512,noverlap=512/16*15,Fs=wav.getframerate(),cmap="gray")
#カラーバーを表示する
fig.colorbar(im).set_label('Intensity [dB]')
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Frequency [Hz]")
#音声ファイルを画像として保存
plt.savefig("./spectrogram_wf_result.png")
#画像を画面に表示
plt.show()
#雑音込みの入力信号も時間領域の波形に戻す
t,data_post=sp.istft(stft_data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#2バイトのデータに変換
data_post=data_post.astype(np.int16)
#スペクトログラムをプロットする
fig=plt.figure(figsize=(10,4))
#スペクトログラムを表示する
spectrum, freqs, t, im=plt.specgram(data_post,NFFT=512,noverlap=512/16*15,Fs=wav.getframerate(),cmap="gray")
#カラーバーを表示する
fig.colorbar(im).set_label('Intensity [dB]')
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Frequency [Hz]")
#音声ファイルを画像として保存
plt.savefig("./spectrogram_noisy.png")
#画像を画面に表示
plt.show()
#waveファイルに書き込む
wave_out = wave.open("./input_wave.wav", 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(wav.getframerate())
#データを書き込み
wave_out.writeframes(data_post)
#ファイルを閉じる
wave_out.close()
#waveファイルを閉じる
wav.close()
================================================
FILE: section2/sample_code_c2_2.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#可視化のためにmatplotlibモジュールをインポート
import matplotlib.pyplot as plt
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#dataの値を2バイトの変数が取り得る値の最大値で正規化
data=data/np.iinfo(np.int16).max
#waveファイルを閉じる
wav.close()
#x軸の値
x=np.array(range(wav.getnframes()))/wav.getframerate()
#音声データをプロットする
plt.figure(figsize=(10,4))
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Value [-1,1]")
#データをプロット
plt.plot(x,data)
#音声ファイルを画像として保存
plt.savefig("./wave_form.png")
#画像を画面に表示
plt.show()
================================================
FILE: section2/sample_code_c2_3.py
================================================
import wave as wave
import numpy as np
import matplotlib.pyplot as plt
#白色雑音のサンプル数を設定
n_sample=40000
#サンプリング周波数
sample_rate=16000
#乱数の種を設定
np.random.seed(0)
#白色雑音を生成
data=np.random.normal(size=n_sample)
#x軸の値
x=np.array(range(n_sample))/sample_rate
#音声データをプロットする
plt.figure(figsize=(10,4))
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Value")
#データをプロット
plt.plot(x,data)
#音声ファイルを画像として保存
plt.savefig("./wgn_wave_form.png")
#画像を画面に表示
plt.show()
================================================
FILE: section2/sample_code_c2_4.py
================================================
import wave as wave
import numpy as np
import matplotlib.pyplot as plt
#白色雑音のサンプル数を設定
n_sample=40000
#サンプリング周波数
sample_rate=16000
#乱数の種を設定
np.random.seed(0)
#白色雑音を生成
data=np.random.normal(scale=0.1,size=n_sample)
#2バイトのデータとして書き込むためにスケールを調整
data_scale_adjust=data*np.iinfo(np.int16).max
#2バイトのデータに変換
data_scale_adjust=data_scale_adjust.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open("./wgn_wave.wav", 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(data_scale_adjust)
#ファイルを閉じる
wave_out.close()
================================================
FILE: section2/sample_code_c2_5.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#可視化のためにmatplotlibモジュールをインポート
import matplotlib.pyplot as plt
#sounddeviceモジュールをインポート
import sounddevice as sd
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#dataを再生する
sd.play(data,wav.getframerate())
print("再生開始")
#再生が終わるまで待つ
status = sd.wait()
================================================
FILE: section2/sample_code_c2_6.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#可視化のためにmatplotlibモジュールをインポート
import matplotlib.pyplot as plt
#sounddeviceモジュールをインポート
import sounddevice as sd
#録音する音声データの長さ (秒)
wave_length=5
#サンプリング周波数
sample_rate=16000
print("録音開始")
#録音開始
data = sd.rec(int(wave_length*sample_rate),sample_rate, channels=1)
#録音が終了するまで待つ
sd.wait()
#2バイトのデータとして書き込むためにスケールを調整
data_scale_adjust=data*np.iinfo(np.int16).max
#2バイトのデータに変換
data_scale_adjust=data_scale_adjust.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open("./record_wave.wav", 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(data_scale_adjust)
#ファイルを閉じる
wave_out.close()
================================================
FILE: section2/sample_code_c2_7.py
================================================
#numpyをインポート
import numpy as np
#複素数データを定義する
z=1.0+2.0j
u=2.0+3.0j
#複素数を表示する
print("z=",z)
print("u=",u)
#実部だけを表示する
print("Real(z)=",np.real(z))
#虚部だけを表示する
print("Imaginary(z)=",np.imag(z))
#複素共役を表示する
print("z^*=",np.conjugate(z))
#絶対値を表示する
print("|z|=",np.abs(z))
#zとuを足す
v=z+u
print("z+u=",v)
#zからuを引く
v=z-u
print("z-u=",v)
#zとuをかける
v=z*u
print("z*u=",v)
#zをuで割る
v=z/u
print("z/u=",v)
================================================
FILE: section2/sample_code_c2_8.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#scipyのsignalモジュールをインポート(stft等信号処理計算用)
import scipy.signal as sp
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(data,fs=wav.getframerate(),window="hann",nperseg=512,noverlap=256)
#短時間フーリエ変換後のデータ形式を確認
print("短時間フーリエ変換後のshape: ",np.shape(stft_data))
#周波数軸の情報
print("周波数軸 [Hz]: ",f)
#時間軸の情報
print("時間軸[sec]: ",t)
#waveファイルを閉じる
wav.close()
================================================
FILE: section2/sample_code_c2_9.py
================================================
#wave形式の音声波形を読み込むためのモジュール(wave)をインポート
import wave as wave
#numpyをインポート(波形データを2byteの数値列に変換するために使用)
import numpy as np
#表示用
import matplotlib.pyplot as plt
#読み込むサンプルファイル
sample_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
#ファイルを読み込む
wav=wave.open(sample_wave_file)
#PCM形式の波形データを読み込み
data=wav.readframes(wav.getnframes())
#dataを2バイトの数値列に変換
data=np.frombuffer(data, dtype=np.int16)
#スペクトログラムをプロットする
fig=plt.figure(figsize=(10,4))
#スペクトログラムを表示する
spectrum, freqs, t, im=plt.specgram(data,NFFT=512,noverlap=512/16*15,Fs=wav.getframerate(),cmap="gray")
#カラーバーを表示する
fig.colorbar(im).set_label('Intensity [dB]')
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Frequency [Hz]")
#音声ファイルを画像として保存
plt.savefig("./spectrogram.png")
#画像を画面に表示
plt.show()
#waveファイルを閉じる
wav.close()
================================================
FILE: section2.md
================================================
## 第2章のサンプルコード
* [音声ファイルを開く](section2/sample_code_c2_1.py)
* [音声ファイルをグラフ化する](section2/sample_code_c2_2.py)
* [白色雑音をグラフ化する](section2/sample_code_c2_3.py)
* [ファイルに音声データを書き込む](section2/sample_code_c2_4.py)
* [音声ファイルを再生する](section2/sample_code_c2_5.py)
* [音声データを録音する](section2/sample_code_c2_6.py)
* [NumPyを用いた複素数の四則演算](section2/sample_code_c2_7.py)
* [stftによる短時間フーリエ変換](section2/sample_code_c2_8.py)
* [短時間フーリエ変換で変換した信号のスペクトログラム表示](section2/sample_code_c2_9.py)
* [短時間逆フーリエ変換により時間周波数領域の信号を時間領域の信号に戻す](section2/sample_code_c2_10.py)
* [特定の周波数を消した音を再生する(高域成分を除去)](section2/sample_code_c2_11.py)
* [特定の周波数を消した音を再生する(低域成分を除去)](section2/sample_code_c2_12.py)
* [スペクトルサブトラクションによる雑音抑圧](section2/sample_code_c2_13.py)
* [ウィナーフィルタによる雑音抑圧](section2/sample_code_c2_14.py)
================================================
FILE: section3/sample_code_c3_1.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#行列を定義
A=np.matrix([[3.,1.,2.],[2.,3.,1.]])
#行列の大きさを表示
print("行列Aの大きさ(M行, N列): ", np.shape(A))
#行列を表示
print("A= \n",A)
#行列Aにスカラーcをかける
c=2.
print("cA= \n",c*A)
#行列Aに行列Bを足す
B=np.matrix([[-1.,2.,4.],[1.,8.,6.]])
print("A+B= \n",A+B)
#行列Aに行列Bをかける
B=np.matrix([[4.,2.],[-1.,3.],[1.,5.]])
print("AB= \n",np.matmul(A,B))
print("AB= \n",np.einsum("mk,kn->mn",A,B))
#行列Aと行列Bのアダマール積
B=np.matrix([[-1.,2.,4.],[1.,8.,6.]])
print("A*B= \n",np.multiply(A,B))
#行列Aの転置
print("A^T= \n",A.T)
print("A^T= \n",np.transpose(A,axes=(1,0)))
print("A^T= \n",np.swapaxes(A,1,0))
#複素行列のエルミート転置
A=np.matrix([[3.,1.+2.j,2.+3.j],[2.,3.-4.j,1.+3.j]])
print("A^H= \n",A.H)
print("A^H= \n",np.swapaxes(np.conjugate(A),1,0))
#行列の積に対するエルミート転置
A=np.matrix([[3.,1.+2.j,2.+3.j],[2.,3.-4.j,1.+3.j]])
B=np.matrix([[4.+4.j,2.-3.j],[-1.+1.j,3.-2.j],[1.+3.j,5.+5.j]])
print("(AB)^H= \n",(np.matmul(A,B)).H)
print("B^H A^H= \n",np.matmul(B.H,A.H))
#単位行列の定義
I=np.eye(N=3)
print("I = \n",I)
================================================
FILE: section3/sample_code_c3_2.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#乱数の種を設定
np.random.seed(0)
#テンソルの大きさを設定
L=10
K=5
M=3
R=3
N=3
#ランダムな複素数のテンソル(ndarray)を定義する
A=np.random.uniform(size=L*K*M*R)+np.random.uniform(size=L*K*M*R)*1.j
A=np.reshape(A,(L,K,M,R))
B=np.random.uniform(size=K*R*N)+np.random.uniform(size=K*R*N)*1.j
B=np.reshape(B,(K,R,N))
#einsumを使って行列積を計算する
C=np.einsum("lkmr,krn->lkmn",A,B)
#行列Cの大きさを表示
print("shape(C): ",np.shape(C))
#l=0,k=0の要素について検算実施
print("A(0,0)B(0,0)=\n",np.matmul(A[0,0,...],B[0,...]))
print("C(0,0)=\n",C[0,0,...])
#einsumを使って行列積をl,k毎に計算した後、かつl方向に和を取る
C=np.einsum("lkmr,krn->kmn",A,B)
#行列Cの大きさを表示
print("shape(C): ",np.shape(C))
#k=0の要素について検算実施
for l in range(L):
if l==0:
C_2=np.matmul(A[l,0,...],B[0,...])
else:
C_2=C_2+np.matmul(A[l,0,...],B[0,...])
print("C_2(0)=\n",C_2)
print("C(0)=\n",C[0,...])
#einsumを使ってアダマール積を計算する
C=np.einsum("lkmn,kmn->lkmn",A,B)
#行列Cの大きさを表示
print("shape(C): ",np.shape(C))
#l=0,k=0の要素について検算実施
print("A(0,0)B(0,0)=\n",np.multiply(A[0,0,...],B[0,...]))
print("C(0,0)=\n",C[0,0,...])
================================================
FILE: section3/sample_code_c3_3.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#乱数の種を設定
np.random.seed(0)
#テンソルの大きさを設定
L=10
K=5
M=3
R=3
S=3
N=3
#ランダムな複素数のテンソル(ndarray)を定義する
A=np.random.uniform(size=L*K*M*R)+np.random.uniform(size=L*K*M*R)*1.j
A=np.reshape(A,(L,K,M,R))
B=np.random.uniform(size=K*R*S)+np.random.uniform(size=K*R*S)*1.j
B=np.reshape(B,(K,R,S))
C=np.random.uniform(size=L*S*N)+np.random.uniform(size=L*S*N)*1.j
C=np.reshape(C,(L,S,N))
#einsumを使って行列積を計算する
D=np.einsum("lkmr,krs,lsn->kmn",A,B,C)
print(np.shape(D))
#k=0の要素について検算実施
for l in range(L):
if l==0:
D_2=np.matmul(np.matmul(A[l,0,...],B[0,...]),C[l])
else:
D_2=D_2+np.matmul(np.matmul(A[l,0,...],B[0,...]),C[l])
print("D_2(0)=\n",D_2)
print("D(0)=\n",D[0,...])
================================================
FILE: section3/sample_code_c3_4.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#乱数の種を設定
np.random.seed(0)
#行列の大きさを設定する
L=10
M=3
N=3
#ランダムな複素数のテンソル(ndarray)を定義する
A=np.random.uniform(size=L*M*N)+np.random.uniform(size=L*M*N)*1.j
A=np.reshape(A,(L,M,N))
#行列式を計算する
detA=np.linalg.det(A)
print("detA(0): ",detA[0])
#全ての要素を3倍した行列の行列式を計算する
det3A=np.linalg.det(3*A)
print("det3A(0): ",det3A[0])
#逆行列を計算する
A_inv=np.linalg.inv(A)
#Aとかけて単位行列になっているかどうかを検算
AA_inv=np.einsum("lmk,lkn->lmn",A,A_inv)
print("単位行列?: \n",AA_inv[0])
A_invA=np.einsum("lmk,lkn->lmn",A_inv,A)
print("単位行列?: \n",A_invA[0])
#一般化逆行列計算
A_inv=np.linalg.pinv(A)
#Aとかけて単位行列になっているかどうかを検算
AA_inv=np.einsum("lmk,lkn->lmn",A,A_inv)
print("単位行列?: \n",AA_inv[0])
A_invA=np.einsum("lmk,lkn->lmn",A_inv,A)
print("単位行列?: \n",A_invA[0])
================================================
FILE: section3/sample_code_c3_5.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#行列を定義
A=np.matrix([[3.,1.,2.],[2.,3.,1.]])
#ベクトルを定義
b=np.array([2.,1.,4.])
#行列を表示
print("A= \n",A)
#ベクトルを表示
print("b= \n",b)
#行列Aにベクトルbをかける
print("Ab= \n",np.dot(A,b))
================================================
FILE: section3/sample_code_c3_6.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#行列を定義
a=np.matrix([3.+2.j,1.-1.j,2.+2.j])
#ベクトルを定義
b=np.array([2.+5.j,1.-1.j,4.+1.j])
#ベクトルの内積計算
print("a^Hb=",np.inner(np.conjugate(a),b))
#ベクトルの内積計算
print("a^Ha=",np.inner(np.conjugate(a),a))
================================================
FILE: section3/sample_code_c3_7.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#乱数の種を設定
np.random.seed(0)
#行列の大きさを設定する
L=10
M=3
N=3
#ランダムな複素数のテンソル(ndarray)を定義する
A=np.random.uniform(size=L*M*N)+np.random.uniform(size=L*M*N)*1.j
A=np.reshape(A,(L,M,N))
#ランダムな複素数のテンソル(ndarray)を定義する
b=np.random.uniform(size=L*M)+np.random.uniform(size=L*M)*1.j
b=np.reshape(b,(L,M))
#行列Aのtrace
print("tr(A)= \n",np.trace(A,axis1=-2,axis2=-1))
#einsumを用いたtrace計算
print("tr(A)= \n",np.einsum("lmm->l",A))
#b^H,A,bの計算
print("b^H A b=\n",np.einsum("lm,lmn,ln->l",np.conjugate(b),A,b))
#b^H,A,bの計算
print("trA bb^H =\n",np.trace(np.einsum("lmn,ln,lk->lmk",A,b,np.conjugate(b)),axis1=-2,axis2=-1))
================================================
FILE: section3/sample_code_c3_8.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#乱数の種を設定
np.random.seed(0)
#行列の大きさを設定する
L=10
M=3
N=3
#ランダムな複素数のテンソル(ndarray)を定義する
A=np.random.uniform(size=L*M*N)+np.random.uniform(size=L*M*N)*1.j
A=np.reshape(A,(L,M,N))
#正定エルミート行列を作る
B=np.einsum("lmk,lnk->lmn",A,np.conjugate(A))
#Aの固有値分解実施
w,v=np.linalg.eig(A)
#固有値と固有ベクトルからAを復元できるか検証
A_reconst=np.einsum("lmk,lk,lkn->lmn",v,w,np.linalg.inv(v))
print("A[0]: \n",A[0])
print("A_reconst[0]: \n",A_reconst[0])
#Bの固有値分解実施
w,v=np.linalg.eigh(B)
#固有値と固有ベクトルからBを復元できるか検証
B_reconst=np.einsum("lmk,lk,lnk->lmn",v,w,np.conjugate(v))
print("B[0]: \n",B[0])
print("B[0]: \n",B_reconst[0])
================================================
FILE: section3/sample_code_c3_9.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#A: ...mn
#B: ...ij
#AとBの最後の二軸以外の次元は一致していることを前提とする
def batch_kron(A,B):
if np.shape(A)[:-2]!=np.shape(B)[:-2]:
print("error")
return None
else:
return(np.reshape(np.einsum("...mn,...ij->...minj",A,B),np.shape(A)[:-2]+(np.shape(A)[-2]*np.shape(B)[-2],np.shape(A)[-1]*np.shape(B)[-1])))
#乱数の種を設定
np.random.seed(0)
#行列の大きさを設定する
L=10
M=3
R=3
N=3
T=3
#ランダムな複素数のテンソル(ndarray)を定義する
A=np.random.uniform(size=L*M*R)+np.random.uniform(size=L*M*R)*1.j
A=np.reshape(A,(L,M,R))
X=np.random.uniform(size=R*N)+np.random.uniform(size=R*N)*1.j
X=np.reshape(X,(R,N))
B=np.random.uniform(size=L*N*T)+np.random.uniform(size=L*N*T)*1.j
B=np.reshape(B,(L,N,T))
D=np.random.uniform(size=L*M*T)+np.random.uniform(size=L*M*T)*1.j
D=np.reshape(D,(L,M,T))
#1. 多次元配列対応版のクロネッカー積batch_kronの出力結果とnumpyのkronの出力結果が一致していることを確認
#多次元配列対応版のクロネッカー積
C=batch_kron(np.transpose(B,(0,2,1)),A)
#numpyのkronでl=0のデータに対してクロネッカー積を計算
C_2=np.kron(np.transpose(B[0,...],(1,0)),A[0,...])
#多次元配列対応版のクロネッカー積とnumpyのkronとの誤差
print("誤差 = ",np.sum(np.abs(C[0,...]-C_2)))
#2. vecAXBとCvecXが一致しているかどうかを確認する
#Xをベクトル化する
vecX=np.reshape(np.transpose(X,[1,0]),(N*R))
#AXBを計算する
AXB=np.einsum("lmr,rn,lnt->lmt",A,X,B)
#AXBをベクトル化する
vecAXB=np.reshape(np.transpose(AXB,[0,2,1]),(L,T*M))
#CvecX
CvecX=np.einsum("lmr,r->lm",C,vecX)
#vecAXBとCvecXが一致しているかどうかを確認する
print("誤差 = ",np.sum(np.abs(vecAXB-CvecX)))
#3. ΣAXB=ΣDを満たすようなXを求める
#vecDを求める
vecD=np.reshape(np.transpose(D,[0,2,1]),(L,T*M))
#vecXを求める
vecX=np.einsum("mr,r->m",np.linalg.inv(np.sum(C,axis=0)), np.sum(vecD,axis=0))
#Xに戻す
X=np.transpose(np.reshape(vecX,(N,R)),(1,0))
#答えがあっているかどうかを確認
sum_AXB=np.einsum("lmr,rn,lnt->mt",A,X,B)
sum_D=np.sum(D,axis=0)
#sum_AXBとsum_Dが一致しているかどうかを確認する
print("誤差 = ",np.sum(np.abs(sum_AXB-sum_D)))
================================================
FILE: section3.md
================================================
## 第3章のサンプルコード
* [行列の基本的な演算](section3/sample_code_c3_1.py)
* [アインシュタイン縮約記法を用いたテンソル計算](section3/sample_code_c3_2.py)
* [アインシュタイン縮約記法を用いたテンソル計算(3つのテンソル)](section3/sample_code_c3_3.py)
* [逆行列演算](section3/sample_code_c3_4.py)
* [行列とベクトルの掛け算](section3/sample_code_c3_5.py)
* [ベクトルの内積計算](section3/sample_code_c3_6.py)
* [行列のトレース計算](section3/sample_code_c3_7.py)
* [固有値計算](section3/sample_code_c3_8.py)
* [クロネッカー積を用いた計算例](section3/sample_code_c3_9.py)
================================================
FILE: section4/sample_code_c4_1.py
================================================
#numpyをインポート(行列を扱う各種関数を含む)
import numpy as np
#可視化のためにmatplotlibモジュールをインポート
import matplotlib.pyplot as plt
#アニメーション用のモジュールをインポート
import matplotlib.animation as animation
#確率密度関数の描画用
from scipy.stats import norm
#混合ガウス分布に基づく乱数を生成する
np.random.seed(0)
#各ガウス分布のサンプル数
n_samples=[200,400,400]
#各ガウス分布の平均
means=[-2,3,5]
#各ガウス分布の分散
sigmas=[3,2,0.5]
#GMMに従う乱数を生成
x=None
for n,mean,sigma in zip(n_samples,means,sigmas):
samples_for_each_dist=np.random.normal(mean,sigma, int(n))
if x is None:
x=samples_for_each_dist
else:
x=np.concatenate((x,samples_for_each_dist))
#モデルパラメータを初期化する
alpha=np.array([1./3.,1./3.,1./3.])
var=np.array([1.,1.,1.])
mu=np.array([-1,0,1])
#GMMを構成するガウス分布の数
n_clusters=len(alpha)
#繰り返し計算でパラメータを最適化する(ここでは100回繰り返す)
n_iterations=101
log_likelihood=np.zeros(n_iterations)
ims=[]
for t in range(n_iterations):
print("t{}".format(t))
if t==0:
alpha_buf=alpha[None,:]
var_buf=var[None,:]
mu_buf=mu[None,:]
else:
alpha_buf=np.concatenate((alpha_buf,alpha[None,:]),axis=0)
var_buf=np.concatenate((var_buf,var[None,:]),axis=0)
mu_buf=np.concatenate((mu_buf,mu[None,:]),axis=0)
#Eステップ
#係数部
coef=alpha/np.sqrt(2.*np.pi*var)
#exponent: n_sample, n_clusters
exponent=-1.*np.power(x[:,None]-mu[None,:],2.)/(2*var[None,:])
#βを求める
beta=coef[None,:]*np.exp(exponent)
likelihood_each_sample=np.maximum(np.sum(beta,axis=1,keepdims=True),1.e-18)
beta=beta/likelihood_each_sample
#対数尤度を求める
current_log_likelihood=np.average(np.log(likelihood_each_sample))
log_likelihood[t]=current_log_likelihood
#Mステップ(パラメータを更新する)
N=np.maximum(np.sum(beta,axis=0),1.e-18)
#事前確率を更新
alpha=N/np.sum(N)
#平均値を更新
mu=np.einsum("ij,i->j",beta,x)/N
#分散を計算
var=np.einsum("ij,ij->j",beta,np.power(x[:,None]-mu[None,:],2.))/N
var=np.maximum(var,1.e-18)
#対数ゆう度をグラフ化する
plt.figure(figsize=(10,4))
plt.plot(np.arange(0,n_iterations,1),log_likelihood,color="black",linewidth=1,label="log likelihood")
plt.xlabel("Number of iterations")
plt.legend()
plt.savefig("./log_likelihood_gmm.png")
plt.show()
#パラメータ更新の様子をアニメーションで表示
def animation_update(t):
plt.cla()
plt.hist(x,bins=50,normed=True,label="observed samples")
xmin=-20
xmax=20
plt.xlim([xmin,xmax])
plt.ylim([0,0.40])
x_range=np.arange(-20,20,0.01)
#GMMを描画する
pdf=None
for alpha,var, mu in zip(alpha_buf[t],var_buf[t],mu_buf[t]):
pdf_each=alpha*norm.pdf(x_range,mu,np.sqrt(var))
if pdf is None:
pdf=pdf_each
else:
pdf=pdf+pdf_each
plt.plot(x_range,pdf,color="black",linewidth=1,label=r"$p(x|\theta^{(t="+str(t)+")})$")
plt.legend()
if t==0:
plt.savefig("./initialized_gmm.png")
if t==n_iterations-1:
plt.savefig("./learned_gmm.png")
#音声データをプロットする
fig=plt.figure(figsize=(10,4))
ani=animation.FuncAnimation(fig,animation_update,interval=200,frames=n_iterations)
plt.show()
================================================
FILE: section4.md
================================================
## 第4章のサンプルコード
* [(参考)EMアルゴリズムによる混合ガウス分布のパラメータ最適化](section4/sample_code_c4_1.py)
================================================
FILE: section5/sample_code_c5_1.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as signal
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_file="./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
wav.close()
#サンプリング周波数
sample_rate=16000
#畳み込むインパルス応答長
n_impulse_length=512
#インパルス応答を乱数で生成(ダミー)
impulse_response=np.random.normal(size=n_impulse_length)
conv_data=signal.convolve(data,impulse_response,mode='full')
#ファイルに書き込む
data_scale_adjust=conv_data*np.iinfo(np.int16).max/20.
data_scale_adjust=data_scale_adjust.astype(np.int16)
wave_out=wave.open("./conv_out.wav","w")
wave_out.setnchannels(1)
wave_out.setsampwidth(2)
wave_out.setframerate(sample_rate)
wave_out.writeframes(data_scale_adjust)
wave_out.close()
================================================
FILE: section5/sample_code_c5_2.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#音声と雑音との比率 [dB]
SNR=90.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標系
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#ファイルに書き込む
for m in range(n_channels):
conv_data=multi_conv_data[m,:]
data_scale_adjust=conv_data*np.iinfo(np.int16).max/20.
data_scale_adjust=data_scale_adjust.astype(np.int16)
wave_out=wave.open("./conv_out_{}.wav".format(m),"w")
wave_out.setnchannels(1)
wave_out.setsampwidth(2)
wave_out.setframerate(sample_rate)
wave_out.writeframes(data_scale_adjust)
wave_out.close()
================================================
FILE: section5/sample_code_c5_3.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#音声と雑音との比率 [dB]
SNR=90.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
[0.03, 0.0, 0.0]
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#ファイルに書き込む
for m in range(n_channels):
conv_data=multi_conv_data[m,:]
data_scale_adjust=conv_data*np.iinfo(np.int16).max/20.
data_scale_adjust=data_scale_adjust.astype(np.int16)
wave_out=wave.open("./conv_out_{}.wav".format(m),"w")
wave_out.setnchannels(1)
wave_out.setsampwidth(2)
wave_out.setframerate(sample_rate)
wave_out.writeframes(data_scale_adjust)
wave_out.close()
================================================
FILE: section5/sample_code_c5_4.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#音声と雑音との比率 [dB]
SNR=90.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.35)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#ファイルに書き込む
for m in range(n_channels):
conv_data=multi_conv_data[m,:]
data_scale_adjust=conv_data*np.iinfo(np.int16).max/20.
data_scale_adjust=data_scale_adjust.astype(np.int16)
wave_out=wave.open("./reverb_conv_out_{}.wav".format(m),"w")
wave_out.setnchannels(1)
wave_out.setsampwidth(2)
wave_out.setframerate(sample_rate)
wave_out.writeframes(data_scale_adjust)
wave_out.close()
================================================
FILE: section5/sample_code_c5_5.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#音声と雑音との比率 [dB]
SNR=10.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.35)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#ファイルに書き込む
for m in range(n_channels):
conv_data=multi_conv_data[m,:]
data_scale_adjust=conv_data*np.iinfo(np.int16).max/20.
data_scale_adjust=data_scale_adjust.astype(np.int16)
wave_out=wave.open("./noise_reverb_conv_out_{}.wav".format(m),"w")
wave_out.setnchannels(1)
wave_out.setsampwidth(2)
wave_out.setframerate(sample_rate)
wave_out.writeframes(data_scale_adjust)
wave_out.close()
================================================
FILE: section5/sample_code_c5_6.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import matplotlib.pyplot as plt
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#音声と雑音との比率 [dB]
SNR=90.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.35)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#インパルス応答を取得する
#room.rirにはマイク,音源の順番で各音源の各マイクのインパルス応答が入っている
impulse_responses=room.rir
impulse_length=np.shape(impulse_responses[0][0])[0]
#残響時間を取得
rt60=pa.experimental.measure_rt60(impulse_responses[0][0],fs=sample_rate)
print("残響時間:{} [sec]".format(rt60))
rir_power=np.square(impulse_responses[0][0])
reverb_power=np.zeros_like(rir_power)
for t in range(impulse_length):
reverb_power[t]=10.*np.log10(np.sum(rir_power[t:])/np.sum(rir_power))
#x軸の値
x=np.array(range(impulse_length))/sample_rate
#音声データをプロットする
plt.figure(figsize=(10,4))
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Value")
#x軸の範囲を設定する
plt.xlim([0,0.5])
#データをプロット
plt.plot(x,impulse_responses[0][0])
#plt.plot(x,reverb_power)
#音声ファイルを画像として保存
plt.savefig("./impulse_responses2.png")
#画像を画面に表示
plt.show()
================================================
FILE: section5/sample_code_c5_7.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import matplotlib.pyplot as plt
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#音声と雑音との比率 [dB]
SNR=90.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=30,absorption=0.2)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#インパルス応答を取得する
#room.rirにはマイク,音源の順番で各音源の各マイクのインパルス応答が入っている
impulse_responses=room.rir
impulse_length=np.shape(impulse_responses[0][0])[0]
#残響時間を取得
rt60=pa.experimental.measure_rt60(impulse_responses[0][0],fs=sample_rate)
print("残響時間:{} [sec]".format(rt60))
rir_power=np.square(impulse_responses[0][0])
reverb_power=np.zeros_like(rir_power)
for t in range(impulse_length):
reverb_power[t]=10.*np.log10(np.sum(rir_power[t:])/np.sum(rir_power))
#x軸の値
x=np.array(range(impulse_length))/sample_rate
#音声データをプロットする
plt.figure(figsize=(10,4))
#x軸のラベル
plt.xlabel("Time [sec]")
#y軸のラベル
plt.ylabel("Value")
#x軸の範囲を設定する
plt.xlim([0,0.5])
#データをプロット
plt.plot(x,impulse_responses[0][0])
#plt.plot(x,reverb_power)
#音声ファイルを画像として保存
plt.savefig("./impulse_responses2.png")
#画像を画面に表示
plt.show()
================================================
FILE: section5.md
================================================
## 第5章のサンプルコード
* [インパルス応答の畳み込みの例](section5/sample_code_c5_1.py)
* [Pyroomacousticsを用いた室内伝達関数のシミュレーションと畳み込み](section5/sample_code_c5_2.py)
* [マイクロホンの数を変更](section5/sample_code_c5_3.py)
* [残響の量を変更](section5/sample_code_c5_4.py)
* [雑音を考慮したシミュレーション](section5/sample_code_c5_5.py)
* [インパルス応答の取得と残響時間(RT60)の取得](section5/sample_code_c5_6.py)
* [インパルス応答の取得と残響時間(RT60)の取得(残響の量を変更)](section5/sample_code_c5_7.py)
================================================
FILE: section6/sample_code_c6_1.py
================================================
import numpy as np
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#サンプリングレート [Hz]
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
).T
#音源の方向
doas=np.array(
[[np.pi/2,0],
[np.pi/2,np.pi]
] )
#音源とマイクロホンの距離
distance=1
#音源の位置ベクトル
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(mic_alignments,source_locations,freqs,is_use_far=False)
#Far仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
far_steering_vectors=calculate_steering_vector(mic_alignments,source_locations,freqs,is_use_far=True)
#内積を計算
inner_product=np.einsum("ksm,ksm->ks",np.conjugate(near_steering_vectors),far_steering_vectors)
print(np.average(np.abs(inner_product)))
================================================
FILE: section6/sample_code_c6_10.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"]
#雑音だけの区間のサンプル数を設定
n_noise_only=40000
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples+n_noise_only])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,n_noise_only:n_noise_only+wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=20.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mlbf_in.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations,freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#雑音だけの区間のフレーム数
n_noise_only_frame=np.sum(t<(n_noise_only/sample_rate))
#共分散行列を計算する
Rcov=np.einsum("mkt,nkt->kmn",stft_data[...,:n_noise_only_frame],np.conjugate(stft_data[...,:n_noise_only_frame]))
#共分散行列の逆行列を計算する
Rcov_inverse=np.linalg.pinv(Rcov)
#フィルタを計算する
Rcov_inverse_a=np.einsum("kmn,kn->km",Rcov_inverse,near_steering_vectors[:,0,:])
a_H_Rcov_inverse_a=np.einsum("kn,kn->k",np.conjugate(near_steering_vectors[:,0,:]),Rcov_inverse_a)
w_mvdr=Rcov_inverse_a/np.maximum(a_H_Rcov_inverse_a,1.e-18)[:,None]
#フィルタをかける
s_hat=np.einsum("km,mkt->kt",np.conjugate(w_mvdr),stft_data)
#ステアリングベクトルをかける
c_hat=np.einsum("kt,km->mkt",s_hat,near_steering_vectors[:,0,:])
#時間領域の波形に戻す
t,mvdr_out=sp.istft(c_hat[0],fs=sample_rate,window="hann",nperseg=N)
#大きさを調整する
mvdr_out=mvdr_out*np.iinfo(np.int16).max/20.
#ファイルに書き込む
write_file_from_time_signal(mvdr_out[n_noise_only:],"./mlbf_out.wav",sample_rate)
================================================
FILE: section6/sample_code_c6_11.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"]
#雑音だけの区間のサンプル数を設定
n_noise_only=40000
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples+n_noise_only])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,n_noise_only:n_noise_only+wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=20.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,n_noise_only:]*np.iinfo(np.int16).max/20.,"./maxsnr_in.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations,freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#雑音だけの区間のフレーム数
n_noise_only_frame=np.sum(t<(n_noise_only/sample_rate))
xx_H=np.einsum("mkt,nkt->ktmn",stft_data,np.conjugate(stft_data))
#雑音の共分散行列 freq,mic,mic
Rn=np.average(xx_H[:,:n_noise_only_frame,...],axis=1)
#入力共分散行列
Rs=np.average(xx_H[:,n_noise_only_frame:,...],axis=1)
#一般化固有値分解
max_snr_filter=None
for k in range(Nk):
w,v=scipy.linalg.eigh(Rs[k,...],Rn[k,...])
if max_snr_filter is None:
max_snr_filter=v[None,:,-1]
else:
max_snr_filter=np.concatenate((max_snr_filter,v[None,:,-1]),axis=0)
Rs_w=np.einsum("kmn,kn->km",Rs,max_snr_filter)
beta=Rs_w[:,0]/np.einsum("km,km->k",np.conjugate(max_snr_filter),Rs_w)
w_max_snr=beta[:,None]*max_snr_filter
#フィルタをかける
c_hat=np.einsum("km,mkt->kt",np.conjugate(w_max_snr),stft_data)
#時間領域の波形に戻す
t,maxsnr_out=sp.istft(c_hat,fs=sample_rate,window="hann",nperseg=N)
#大きさを調整する
maxsnr_out=maxsnr_out*np.iinfo(np.int16).max/20.
#ファイルに書き込む
write_file_from_time_signal(maxsnr_out[n_noise_only:],"./maxsnr_out.wav",sample_rate)
================================================
FILE: section6/sample_code_c6_12.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"]
#雑音だけの区間のサンプル数を設定
n_noise_only=40000
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples+n_noise_only])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,n_noise_only:n_noise_only+wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=20.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mwf_in.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations,freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#雑音だけの区間のフレーム数
n_noise_only_frame=np.sum(t<(n_noise_only/sample_rate))
xx_H=np.einsum("mkt,nkt->ktmn",stft_data,np.conjugate(stft_data))
#雑音の倍率
mu=1.0
#雑音の共分散行列 freq,mic,mic
Rn=np.average(xx_H[:,:n_noise_only_frame,...],axis=1)
#入力共分散行列
Rs=np.average(xx_H[:,n_noise_only_frame:,...],axis=1)-Rn
#固有値分解をして半正定行列に変換
w,v=np.linalg.eigh(Rs)
Rs_org=Rs.copy()
w[np.real(w)<0]=0
Rs=np.einsum("kmi,ki,kni->kmn",v,w,np.conjugate(v))
#入力共分散行列
Rs_muRn=Rs+Rn*mu
invRs_muRn=np.linalg.pinv(Rs_muRn)
#フィルタ生成
W_mwf=np.einsum("kmi,kin->kmn",invRs_muRn,Rs)
#フィルタをかける
c_hat=np.einsum("kim,ikt->mkt",np.conjugate(W_mwf),stft_data)
#時間領域の波形に戻す
t,mwf_out=sp.istft(c_hat[0],fs=sample_rate,window="hann",nperseg=N)
#大きさを調整する
mwf_out=mwf_out*np.iinfo(np.int16).max/20.
#ファイルに書き込む
write_file_from_time_signal(mwf_out[n_noise_only:],"./mwf_out_{}.wav".format(mu),sample_rate)
================================================
FILE: section6/sample_code_c6_13.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#遅延和アレイを実行する
#x:入力信号( M, Nk, Lt)
#a:ステアリングベクトル(Nk, M)
#return y 出力信号(M, Nk, Lt)
def execute_dsbf(x,a):
#遅延和アレイを実行する
s_hat=np.einsum("km,mkt->kt",np.conjugate(a),x)
#ステアリングベクトルをかける
c_hat=np.einsum("kt,km->mkt",s_hat,a)
return(c_hat)
#MVDRを実行する
#x:入力信号( M, Nk, Lt)
#y:共分散行列を計算する信号(M,Nk,Lt)
#a:ステアリングベクトル(Nk, M)
#return y 出力信号(M, Nk, Lt)
def execute_mvdr(x,y,a):
#共分散行列を計算する
Rcov=np.einsum("mkt,nkt->kmn",y,np.conjugate(y))
#共分散行列の逆行列を計算する
Rcov_inverse=np.linalg.pinv(Rcov)
#フィルタを計算する
Rcov_inverse_a=np.einsum("kmn,kn->km",Rcov_inverse,a)
a_H_Rcov_inverse_a=np.einsum("kn,kn->k",np.conjugate(a),Rcov_inverse_a)
w_mvdr=Rcov_inverse_a/np.maximum(a_H_Rcov_inverse_a,1.e-18)[:,None]
#フィルタをかける
s_hat=np.einsum("km,mkt->kt",np.conjugate(w_mvdr),x)
#ステアリングベクトルをかける
c_hat=np.einsum("kt,km->mkt",s_hat,a)
return(c_hat)
#MaxSNRを実行する
#x:入力信号( M, Nk, Lt)
#y:共分散行列を計算する信号(M,Nk,Lt)
#return y 出力信号(M, Nk, Lt)
def execute_max_snr(x,y):
#雑音の共分散行列 freq,mic,mic
Rn=np.average(np.einsum("mkt,nkt->ktmn",y,np.conjugate(y)),axis=1)
#入力共分散行列
Rs=np.average(np.einsum("mkt,nkt->ktmn",x,np.conjugate(x)),axis=1)
#周波数の数を取得
Nk=np.shape(Rs)[0]
#一般化固有値分解
max_snr_filter=None
for k in range(Nk):
w,v=scipy.linalg.eigh(Rs[k,...],Rn[k,...])
if max_snr_filter is None:
max_snr_filter=v[None,:,-1]
else:
max_snr_filter=np.concatenate((max_snr_filter,v[None,:,-1]),axis=0)
Rs_w=np.einsum("kmn,kn->km",Rs,max_snr_filter)
beta=Rs_w/np.einsum("km,km->k",np.conjugate(max_snr_filter),Rs_w)[:,None]
w_max_snr=beta[:,None,:]*max_snr_filter[...,None]
#フィルタをかける
c_hat=np.einsum("kim,ikt->mkt",np.conjugate(w_max_snr),x)
return(c_hat)
#SNRをはかる
#desired: 目的音、Lt
#out: 雑音除去後の信号 Lt
def calculate_snr(desired,out):
wave_length=np.minimum(np.shape(desired)[0],np.shape(out)[0])
#消し残った雑音
desired=desired[:wave_length]
out=out[:wave_length]
noise=desired-out
snr=10.*np.log10(np.sum(np.square(desired))/np.sum(np.square(noise)))
return(snr)
#ファイルに書き込む
#MWFを実行する
#x:入力信号( M, Nk, Lt)
#y:共分散行列を計算する信号(M,Nk,Lt)
#mu: 雑音共分散行列の係数
#return y 出力信号(M, Nk, Lt)
def execute_mwf(x,y,mu):
#雑音の共分散行列 freq,mic,mic
Rn=np.average(np.einsum("mkt,nkt->ktmn",y,np.conjugate(y)),axis=1)
#入力共分散行列
Rs=np.average(np.einsum("mkt,nkt->ktmn",x,np.conjugate(x)),axis=1)
#固有値分解をして半正定行列に変換
w,v=np.linalg.eigh(Rs)
Rs_org=Rs.copy()
w[np.real(w)<0]=0
Rs=np.einsum("kmi,ki,kni->kmn",v,w,np.conjugate(v))
#入力共分散行列
Rs_muRn=Rs+Rn*mu
invRs_muRn=np.linalg.pinv(Rs_muRn)
#フィルタ生成
W_mwf=np.einsum("kmi,kin->kmn",invRs_muRn,Rs)
#フィルタをかける
c_hat=np.einsum("kim,ikt->mkt",np.conjugate(W_mwf),x)
return(c_hat)
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#雑音だけの区間のサンプル数を設定
n_noise_only=40000
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples+n_noise_only])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,n_noise_only:n_noise_only+wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#シミュレーションで用いる音源数
n_sim_sources=1
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=10.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[x, 0.0, 0.0] for x in np.arange(-0.01,0.02,0.02)
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
room_no_noise = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2., np.pi]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sim_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
if s==0:
room_no_noise.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
room_no_noise.simulate(snr=90)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
multi_conv_data_no_noise=room_no_noise.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_no_noise[0,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mwf_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mwf_in.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations,freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#雑音だけの区間のフレーム数
n_noise_only_frame=np.sum(t<(n_noise_only/sample_rate))
#雑音だけのデータ
noise_data=stft_data[...,:n_noise_only_frame]
#MWFの雑音の倍率
mu=1.0
#それぞれのフィルタを実行する
dsbf_out=execute_dsbf(stft_data,near_steering_vectors[:,0,:])
mvdr_out=execute_mvdr(stft_data,stft_data,near_steering_vectors[:,0,:])
mlbf_out=execute_mvdr(stft_data,noise_data,near_steering_vectors[:,0,:])
max_snr_out=execute_max_snr(stft_data,noise_data)
mwf_out=execute_mwf(stft_data,noise_data,mu)
#評価するマイクロホン
eval_mic_index=0
#時間領域の波形に戻す
t,dsbf_out=sp.istft(dsbf_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,mvdr_out=sp.istft(mvdr_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,mlbf_out=sp.istft(mlbf_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,max_snr_out=sp.istft(max_snr_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,mwf_out=sp.istft(mwf_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
#SNRをはかる
snr_pre=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],multi_conv_data[eval_mic_index,n_noise_only:])
snr_dsbf_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],dsbf_out[n_noise_only:])
snr_mvdr_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],mvdr_out[n_noise_only:])
snr_mlbf_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],mlbf_out[n_noise_only:])
snr_max_snr_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],max_snr_out[n_noise_only:])
snr_mwf_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],mwf_out[n_noise_only:])
#ファイルに書き込む
write_file_from_time_signal(multi_conv_data[eval_mic_index,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mix.wav",sample_rate)
write_file_from_time_signal(multi_conv_data_no_noise[eval_mic_index,n_noise_only:]*np.iinfo(np.int16).max/20.,"./desired.wav",sample_rate)
write_file_from_time_signal(dsbf_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./dsbf_out.wav",sample_rate)
write_file_from_time_signal(mvdr_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./mvdr_out.wav",sample_rate)
write_file_from_time_signal(mlbf_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./mlbf_out.wav",sample_rate)
write_file_from_time_signal(max_snr_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./max_snr_out.wav",sample_rate)
write_file_from_time_signal(mwf_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./mwf_out.wav",sample_rate)
print("method: ", "DSBF", "MVDR", "MLBF", "MaxSNR", "MWF")
print("Δsnr [dB]: {:.2f} {:.2f} {:.2f} {:.2f} {:.2f}".format(snr_dsbf_post-snr_pre,snr_mvdr_post-snr_pre,snr_mlbf_post-snr_pre,snr_max_snr_post-snr_pre,snr_mwf_post-snr_pre))
================================================
FILE: section6/sample_code_c6_14.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
import scipy as scipy
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#遅延和アレイを実行する
#x:入力信号( M, Nk, Lt)
#a:ステアリングベクトル(Nk, M)
#return y 出力信号(M, Nk, Lt)
def execute_dsbf(x,a):
#遅延和アレイを実行する
s_hat=np.einsum("km,mkt->kt",np.conjugate(a),x)
#ステアリングベクトルをかける
c_hat=np.einsum("kt,km->mkt",s_hat,a)
return(c_hat)
#MVDRを実行する
#x:入力信号( M, Nk, Lt)
#y:共分散行列を計算する信号(M,Nk,Lt)
#a:ステアリングベクトル(Nk, M)
#return y 出力信号(M, Nk, Lt)
def execute_mvdr(x,y,a):
#共分散行列を計算する
Rcov=np.einsum("mkt,nkt->kmn",y,np.conjugate(y))
#共分散行列の逆行列を計算する
Rcov_inverse=np.linalg.pinv(Rcov)
#フィルタを計算する
Rcov_inverse_a=np.einsum("kmn,kn->km",Rcov_inverse,a)
a_H_Rcov_inverse_a=np.einsum("kn,kn->k",np.conjugate(a),Rcov_inverse_a)
w_mvdr=Rcov_inverse_a/np.maximum(a_H_Rcov_inverse_a,1.e-18)[:,None]
#フィルタをかける
s_hat=np.einsum("km,mkt->kt",np.conjugate(w_mvdr),x)
#ステアリングベクトルをかける
c_hat=np.einsum("kt,km->mkt",s_hat,a)
return(c_hat)
#MaxSNRを実行する
#x:入力信号( M, Nk, Lt)
#y:共分散行列を計算する信号(M,Nk,Lt)
#return y 出力信号(M, Nk, Lt)
def execute_max_snr(x,y):
#雑音の共分散行列 freq,mic,mic
Rn=np.average(np.einsum("mkt,nkt->ktmn",y,np.conjugate(y)),axis=1)
#入力共分散行列
Rs=np.average(np.einsum("mkt,nkt->ktmn",x,np.conjugate(x)),axis=1)
#周波数の数を取得
Nk=np.shape(Rs)[0]
#一般化固有値分解
max_snr_filter=None
for k in range(Nk):
w,v=scipy.linalg.eigh(Rs[k,...],Rn[k,...])
if max_snr_filter is None:
max_snr_filter=v[None,:,-1]
else:
max_snr_filter=np.concatenate((max_snr_filter,v[None,:,-1]),axis=0)
Rs_w=np.einsum("kmn,kn->km",Rs,max_snr_filter)
beta=Rs_w/np.einsum("km,km->k",np.conjugate(max_snr_filter),Rs_w)[:,None]
w_max_snr=beta[:,None,:]*max_snr_filter[...,None]
#フィルタをかける
c_hat=np.einsum("kim,ikt->mkt",np.conjugate(w_max_snr),x)
return(c_hat)
#SNRをはかる
#desired: 目的音、Lt
#out: 雑音除去後の信号 Lt
def calculate_snr(desired,out):
wave_length=np.minimum(np.shape(desired)[0],np.shape(out)[0])
#消し残った雑音
desired=desired[:wave_length]
out=out[:wave_length]
noise=desired-out
snr=10.*np.log10(np.sum(np.square(desired))/np.sum(np.square(noise)))
return(snr)
#ファイルに書き込む
#MWFを実行する
#x:入力信号( M, Nk, Lt)
#y:共分散行列を計算する信号(M,Nk,Lt)
#mu: 雑音共分散行列の係数
#return y 出力信号(M, Nk, Lt)
def execute_mwf(x,y,mu):
#雑音の共分散行列 freq,mic,mic
Rn=np.average(np.einsum("mkt,nkt->ktmn",y,np.conjugate(y)),axis=1)
#入力共分散行列
Rs=np.average(np.einsum("mkt,nkt->ktmn",x,np.conjugate(x)),axis=1)
#固有値分解をして半正定行列に変換
w,v=np.linalg.eigh(Rs)
Rs_org=Rs.copy()
w[np.real(w)<0]=0
Rs=np.einsum("kmi,ki,kni->kmn",v,w,np.conjugate(v))
#入力共分散行列
Rs_muRn=Rs+Rn*mu
invRs_muRn=np.linalg.pinv(Rs_muRn)
#フィルタ生成
W_mwf=np.einsum("kmi,kin->kmn",invRs_muRn,Rs)
#フィルタをかける
c_hat=np.einsum("kim,ikt->mkt",np.conjugate(W_mwf),x)
return(c_hat)
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#雑音だけの区間のサンプル数を設定
n_noise_only=40000
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples+n_noise_only])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,n_noise_only:n_noise_only+wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#シミュレーションで用いる音源数
n_sim_sources=2
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=int(N/2+1)
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=10.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[x, 0.0, 0.0] for x in np.arange(-0.01,0.02,0.02)
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
room_no_noise = pa.ShoeBox(room_dim, fs=sample_rate, max_order=17,absorption=0.4)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
room_no_noise.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2., np.pi]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sim_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
if s==0:
room_no_noise.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
room_no_noise.simulate(snr=90)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
multi_conv_data_no_noise=room_no_noise.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data_no_noise[0,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mwf_clean.wav",sample_rate)
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mwf_in.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations,freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#雑音だけの区間のフレーム数
n_noise_only_frame=np.sum(t<(n_noise_only/sample_rate))
#雑音だけのデータ
noise_data=stft_data[...,:n_noise_only_frame]
#MWFの雑音の倍率
mu=1.0
#それぞれのフィルタを実行する
dsbf_out=execute_dsbf(stft_data,near_steering_vectors[:,0,:])
mvdr_out=execute_mvdr(stft_data,stft_data,near_steering_vectors[:,0,:])
mlbf_out=execute_mvdr(stft_data,noise_data,near_steering_vectors[:,0,:])
max_snr_out=execute_max_snr(stft_data,noise_data)
mwf_out=execute_mwf(stft_data,noise_data,mu)
#評価するマイクロホン
eval_mic_index=0
#時間領域の波形に戻す
t,dsbf_out=sp.istft(dsbf_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,mvdr_out=sp.istft(mvdr_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,mlbf_out=sp.istft(mlbf_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,max_snr_out=sp.istft(max_snr_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
t,mwf_out=sp.istft(mwf_out[eval_mic_index],fs=sample_rate,window="hann",nperseg=N)
#SNRをはかる
snr_pre=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],multi_conv_data[eval_mic_index,n_noise_only:])
snr_dsbf_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],dsbf_out[n_noise_only:])
snr_mvdr_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],mvdr_out[n_noise_only:])
snr_mlbf_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],mlbf_out[n_noise_only:])
snr_max_snr_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],max_snr_out[n_noise_only:])
snr_mwf_post=calculate_snr(multi_conv_data_no_noise[eval_mic_index,n_noise_only:],mwf_out[n_noise_only:])
#ファイルに書き込む
write_file_from_time_signal(multi_conv_data[eval_mic_index,n_noise_only:]*np.iinfo(np.int16).max/20.,"./mix.wav",sample_rate)
write_file_from_time_signal(multi_conv_data_no_noise[eval_mic_index,n_noise_only:]*np.iinfo(np.int16).max/20.,"./desired.wav",sample_rate)
write_file_from_time_signal(dsbf_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./dsbf_out.wav",sample_rate)
write_file_from_time_signal(mvdr_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./mvdr_out.wav",sample_rate)
write_file_from_time_signal(mlbf_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./mlbf_out.wav",sample_rate)
write_file_from_time_signal(max_snr_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./max_snr_out.wav",sample_rate)
write_file_from_time_signal(mwf_out[n_noise_only:]*np.iinfo(np.int16).max/20.,"./mwf_out.wav",sample_rate)
print("method: ", "DSBF", "MVDR", "MLBF", "MaxSNR", "MWF")
print("Δsnr [dB]: {:.2f} {:.2f} {:.2f} {:.2f} {:.2f}".format(snr_dsbf_post-snr_pre,snr_mvdr_post-snr_pre,snr_mlbf_post-snr_pre,snr_max_snr_post-snr_pre,snr_mwf_post-snr_pre))
================================================
FILE: section6/sample_code_c6_2.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=20.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0]*np.iinfo(np.int16).max/20.,"./mix_in.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations,freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#遅延和アレイを実行する
s_hat=np.einsum("ksm,mkt->skt",np.conjugate(near_steering_vectors),stft_data)
#ステアリングベクトルをかける
c_hat=np.einsum("skt,ksm->mskt",s_hat,near_steering_vectors)
#時間領域の波形に戻す
t,ds_out=sp.istft(c_hat[0],fs=sample_rate,window="hann",nperseg=N)
#大きさを調整する
ds_out=ds_out*np.iinfo(np.int16).max/20.
#ファイルに書き込む
write_file_from_time_signal(ds_out,"./ds_out.wav",sample_rate)
================================================
FILE: section6/sample_code_c6_3.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=20.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[[x,0.0,0.0] for x in np.arange(-0.31,0.32,0.02)]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0]*np.iinfo(np.int16).max/20.,"./ds_in_m32.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations,freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#遅延和アレイを実行する
s_hat=np.einsum("ksm,mkt->skt",np.conjugate(near_steering_vectors),stft_data)
#ステアリングベクトルをかける
c_hat=np.einsum("skt,ksm->mskt",s_hat,near_steering_vectors)
#時間領域の波形に戻す
t,ds_out=sp.istft(c_hat[0],fs=sample_rate,window="hann",nperseg=N)
#大きさを調整する
ds_out=ds_out*np.iinfo(np.int16).max/20.
#ファイルに書き込む
write_file_from_time_signal(ds_out,"./ds_out_m32.wav",sample_rate)
================================================
FILE: section6/sample_code_c6_4.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=90.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[
[-0.01, 0.0, 0.0],
[0.01, 0.0, 0.0],
]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0]*np.iinfo(np.int16).max/20.,"./ds_in.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations[:,:1],freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#遅延和アレイを実行する
s_hat=np.einsum("ksm,mkt->skt",np.conjugate(near_steering_vectors),stft_data)
#ステアリングベクトルをかける
c_hat=np.einsum("skt,ksm->mskt",s_hat,near_steering_vectors)
#時間領域の波形に戻す
t,ds_out=sp.istft(c_hat[0],fs=sample_rate,window="hann",nperseg=N)
#大きさを調整する
ds_out=ds_out*np.iinfo(np.int16).max/20.
#ファイルに書き込む
write_file_from_time_signal(ds_out,"./ds_out.wav",sample_rate)
================================================
FILE: section6/sample_code_c6_5.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#2バイトに変換してファイルに保存
#signal: time-domain 1d array (float)
#file_name: 出力先のファイル名
#sample_rate: サンプリングレート
def write_file_from_time_signal(signal,file_name,sample_rate):
#2バイトのデータに変換
signal=signal.astype(np.int16)
#waveファイルに書き込む
wave_out = wave.open(file_name, 'w')
#モノラル:1、ステレオ:2
wave_out.setnchannels(1)
#サンプルサイズ2byte
wave_out.setsampwidth(2)
#サンプリング周波数
wave_out.setframerate(sample_rate)
#データを書き込み
wave_out.writeframes(signal)
#ファイルを閉じる
wave_out.close()
#乱数の種を初期化
np.random.seed(0)
#畳み込みに用いる音声波形
clean_wave_files=["./CMU_ARCTIC/cmu_us_aew_arctic/wav/arctic_a0001.wav","./CMU_ARCTIC/cmu_us_axb_arctic/wav/arctic_a0002.wav"]
#音源数
n_sources=len(clean_wave_files)
#長さを調べる
n_samples=0
#ファイルを読み込む
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
if n_samples<wav.getnframes():
n_samples=wav.getnframes()
wav.close()
clean_data=np.zeros([n_sources,n_samples])
#ファイルを読み込む
s=0
for clean_wave_file in clean_wave_files:
wav=wave.open(clean_wave_file)
data=wav.readframes(wav.getnframes())
data=np.frombuffer(data, dtype=np.int16)
data=data/np.iinfo(np.int16).max
clean_data[s,:wav.getnframes()]=data
wav.close()
s=s+1
# シミュレーションのパラメータ
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#音声と雑音との比率 [dB]
SNR=90.
#部屋の大きさ
room_dim = np.r_[10.0, 10.0, 10.0]
#マイクロホンアレイを置く部屋の場所
mic_array_loc = room_dim / 2 + np.random.randn(3) * 0.1
#マイクロホンアレイのマイク配置
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[[x,0.0,0.0] for x in np.arange(-0.31,0.32,0.02)]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#マイクロホンアレイの座標
R=mic_alignments .T+mic_array_loc[:,None]
# 部屋を生成する
room = pa.ShoeBox(room_dim, fs=sample_rate, max_order=0)
# 用いるマイクロホンアレイの情報を設定する
room.add_microphone_array(pa.MicrophoneArray(R, fs=room.fs))
#音源の場所
doas=np.array(
[[np.pi/2., 0],
[np.pi/2.,np.pi/2.]
] )
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
source_locations += mic_array_loc[:, None]
#各音源をシミュレーションに追加する
for s in range(n_sources):
clean_data[s]/= np.std(clean_data[s])
room.add_source(source_locations[:, s], signal=clean_data[s])
#シミュレーションを回す
room.simulate(snr=SNR)
#畳み込んだ波形を取得する(チャンネル、サンプル)
multi_conv_data=room.mic_array.signals
#畳み込んだ波形をファイルに書き込む
write_file_from_time_signal(multi_conv_data[0]*np.iinfo(np.int16).max/20.,"./ds_interference_in_m32.wav",sample_rate)
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(R,source_locations[:,:1],freqs,is_use_far=False)
#短時間フーリエ変換を行う
f,t,stft_data=sp.stft(multi_conv_data,fs=sample_rate,window="hann",nperseg=N)
#遅延和アレイを実行する
s_hat=np.einsum("ksm,mkt->skt",np.conjugate(near_steering_vectors),stft_data)
#ステアリングベクトルをかける
c_hat=np.einsum("skt,ksm->mskt",s_hat,near_steering_vectors)
#時間領域の波形に戻す
t,ds_out=sp.istft(c_hat[0],fs=sample_rate,window="hann",nperseg=N)
#大きさを調整する
ds_out=ds_out*np.iinfo(np.int16).max/20.
#ファイルに書き込む
write_file_from_time_signal(ds_out,"./ds_interference_out_m32.wav",sample_rate)
================================================
FILE: section6/sample_code_c6_6.py
================================================
import numpy as np
import scipy.signal as sp
import matplotlib.pyplot as plt
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[[x,0.0,0.0] for x in np.arange(-0.01,0.02,0.02)]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#音源の場所
doas=np.array(
[[np.pi/2.,theta] for theta in np.arange(-np.pi,np.pi,1./180.*np.pi)]
)
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(mic_alignments.T,source_locations,freqs,is_use_far=False)
#theta=0に最も近いステアリングベクトルを取り出す
desired_index=np.argmin(np.abs(doas[:,1]),axis=0)
#所望音のステアリングベクトル
desired_steering_vector=near_steering_vectors[:,desired_index,:]
#内積計算
directivity_pattern=np.square(np.abs(np.einsum("km,ksm->ks",np.conjugate(desired_steering_vector),near_steering_vectors)))
#スタイル
plt.style.use("grayscale")
#音声データをプロットする
fig=plt.figure(figsize=(7,7))
# plot
ax = plt.subplot(111, projection="polar")
#グラフの向き、グリッドの線種を指定
ax.set_theta_zero_location('N')
ax.set_theta_direction('clockwise')
ax.grid(linestyle="--")
#y軸のラベル調整
ax.yaxis.labelpad = -250
ylabel=plt.ylabel("Response [dB]")
ylabel.set_position((0, 0.6))
ylabel.set_rotation(0)
plt.yticks([-20,-10,0])
plt.ylim([-30,0])
#x軸のラベル
plt.xlabel("Azimuth [degrees]")
#描画する周波数
draw_freqs=np.array([1000,2000,3000,4000])
draw_freq_list=np.argmin(np.abs(freqs[:,None]-draw_freqs[None,:]),axis=0)
for draw_freq_index in draw_freq_list:
#周波数毎に指向特性を描画
plt.plot(doas[:,1], 10.*np.log10(directivity_pattern[draw_freq_index,:]),lw=3,label="{} [Hz]".format(freqs[draw_freq_index]))
plt.legend(loc=(0.2,0.6))
#音声ファイルを画像として保存
plt.savefig("./directivity_pattern.png")
#画像を画面に表示
plt.show()
================================================
FILE: section6/sample_code_c6_7.py
================================================
import numpy as np
import scipy.signal as sp
import matplotlib.pyplot as plt
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(steering_vector,2,axis=2,keepdims=True)
return(steering_vector)
#サンプリング周波数
sample_rate=16000
#フレームサイズ
N=1024
#周波数の数
Nk=N/2+1
#各ビンの周波数
freqs=np.arange(0,Nk,1)*sample_rate/N
#マイクロホンアレイのマイク配置
mic_alignments = np.array(
[[x,0.0,0.0] for x in np.arange(-0.31,0.32,0.02)]
)
#マイクロホン数
n_channels=np.shape(mic_alignments)[0]
#音源の場所
doas=np.array(
[[np.pi/2.,theta] for theta in np.arange(-np.pi,np.pi,1./180.*np.pi)]
)
#音源とマイクロホンの距離
distance=1.
source_locations=np.zeros((3, doas.shape[0]), dtype=doas.dtype)
source_locations[0, :] = np.cos(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[1, :] = np.sin(doas[:, 1]) * np.sin(doas[:, 0])
source_locations[2, :] = np.cos(doas[:, 0])
source_locations *= distance
#Near仮定に基づくステアリングベクトルを計算: steering_vectors(Nk x Ns x M)
near_steering_vectors=calculate_steering_vector(mic_alignments.T,source_locations,freqs,is_use_far=False)
#theta=0に最も近いステアリングベクトルを取り出す
desired_index=np.argmin(np.abs(doas[:,1]),axis=0)
#所望音のステアリングベクトル
desired_steering_vector=near_steering_vectors[:,desired_index,:]
#内積計算
directivity_pattern=np.square(np.abs(np.einsum("km,ksm->ks",np.conjugate(desired_steering_vector),near_steering_vectors)))
#スタイル
plt.style.use("grayscale")
#音声データをプロットする
fig=plt.figure(figsize=(7,7))
# plot
ax = plt.subplot(111, projection="polar")
#グラフの向き、グリッドの線種を指定
ax.set_theta_zero_location('N')
ax.set_theta_direction('clockwise')
ax.grid(linestyle="--")
ax.yaxis.labelpad = -30
#x軸のラベル
plt.xlabel("Azimuth [degrees]")
#y軸のラベル
ylabel=plt.ylabel("Response [dB]")
ylabel.set_position((0, 0.6))
ylabel.set_rotation(0)
plt.yticks([-20,-10,0])
plt.ylim([-30,0])
#描画する周波数
draw_freqs=np.array([1000,2000,3000,4000])
draw_freq_list=np.argmin(np.abs(freqs[:,None]-draw_freqs[None,:]),axis=0)
for draw_freq_index in draw_freq_list:
#周波数毎に指向特性を描画
plt.plot(doas[:,1], 10.*np.log10(directivity_pattern[draw_freq_index,:]),lw=3,label="{} [Hz]".format(freqs[draw_freq_index]))
plt.legend(loc=(0.2,0.6))
#音声ファイルを画像として保存
plt.savefig("./directivity_pattern_m32.png")
#画像を画面に表示
plt.show()
================================================
FILE: section6/sample_code_c6_8.py
================================================
import wave as wave
import pyroomacoustics as pa
import numpy as np
import scipy.signal as sp
#ステアリングベクトルを算出
#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]
#source_position: 3x Ns dimensional ndarray [[x,y,z],[x,y,z] ]
#freqs: Nk dimensional array [f1,f2,f3...]
#sound_speed: 音速 [m/s]
#is_use_far: Farを使う場合はTrue, Nearの場合はFalse,
#return: steering vector (Nk x Ns x M)
def calculate_steering_vector(mic_alignments,source_locations,freqs,sound_speed=340,is_use_far=False):
#マイク数を取得
n_channels=np.shape(mic_alignments)[1]
#音源数を取得
n_source=np.shape(source_locations)[1]
if is_use_far==True:
#音源位置を正規化
norm_source_locations=source_locations/np.linalg.norm(source_locations,2,axis=0,keepdims=True)
#位相を求める
steering_phase=np.einsum('k,ism,ism->ksm',2.j*np.pi/sound_speed*freqs,norm_source_locations[...,None],mic_alignments[:,None,:])
#ステアリングベクトルを算出
steering_vector=1./np.sqrt(n_channels)*np.exp(steering_phase)
return(steering_vector)
else:
#音源とマイクの距離を求める
#distance: Ns x Nm
distance=np.sqrt(np.sum(np.square(source_locations[...,None]-mic_alignments[:,None,:]),axis=0))
#遅延時間(delay) [sec]
delay=distance/sound_speed
#ステアリングベクトルの位相を求める
steering_phase=np.einsum('k,sm->ksm',-2.j*np.pi*freqs,delay)
#音量の減衰
steering_decay_ratio=1./distance
#ステアリングベクトルを求める
steering_vector=steering_decay_ratio[None,...]*np.exp(steering_phase)
#大きさを1で正規化する
steering_vector=steering_vector/np.linalg.norm(ste
gitextract_ib0mjebm/ ├── LICENSE.txt ├── README.md ├── errata.md ├── install.md ├── section10/ │ ├── sample_code_c10_1.py │ └── sample_code_c10_2.py ├── section10.md ├── section11/ │ ├── sample_code_c11_1.py │ └── sample_code_c11_2.py ├── section11.md ├── section2/ │ ├── sample_code_c2_1.py │ ├── sample_code_c2_10.py │ ├── sample_code_c2_11.py │ ├── sample_code_c2_12.py │ ├── sample_code_c2_13.py │ ├── sample_code_c2_14.py │ ├── sample_code_c2_2.py │ ├── sample_code_c2_3.py │ ├── sample_code_c2_4.py │ ├── sample_code_c2_5.py │ ├── sample_code_c2_6.py │ ├── sample_code_c2_7.py │ ├── sample_code_c2_8.py │ └── sample_code_c2_9.py ├── section2.md ├── section3/ │ ├── sample_code_c3_1.py │ ├── sample_code_c3_2.py │ ├── sample_code_c3_3.py │ ├── sample_code_c3_4.py │ ├── sample_code_c3_5.py │ ├── sample_code_c3_6.py │ ├── sample_code_c3_7.py │ ├── sample_code_c3_8.py │ └── sample_code_c3_9.py ├── section3.md ├── section4/ │ └── sample_code_c4_1.py ├── section4.md ├── section5/ │ ├── sample_code_c5_1.py │ ├── sample_code_c5_2.py │ ├── sample_code_c5_3.py │ ├── sample_code_c5_4.py │ ├── sample_code_c5_5.py │ ├── sample_code_c5_6.py │ └── sample_code_c5_7.py ├── section5.md ├── section6/ │ ├── sample_code_c6_1.py │ ├── sample_code_c6_10.py │ ├── sample_code_c6_11.py │ ├── sample_code_c6_12.py │ ├── sample_code_c6_13.py │ ├── sample_code_c6_14.py │ ├── sample_code_c6_2.py │ ├── sample_code_c6_3.py │ ├── sample_code_c6_4.py │ ├── sample_code_c6_5.py │ ├── sample_code_c6_6.py │ ├── sample_code_c6_7.py │ ├── sample_code_c6_8.py │ └── sample_code_c6_9.py ├── section6.md ├── section7/ │ ├── sample_code_c7_1.py │ ├── sample_code_c7_2.py │ ├── sample_code_c7_3.py │ ├── sample_code_c7_4.py │ └── sample_code_c7_5.py ├── section7.md ├── section8/ │ ├── sample_code_c8_1.py │ ├── sample_code_c8_2.py │ ├── sample_code_c8_3.py │ └── sample_code_c8_4.py ├── section8.md ├── section9/ │ ├── sample_code_c9_1.py │ └── sample_code_c9_2.py └── section9.md
SYMBOL INDEX (161 symbols across 31 files) FILE: section10/sample_code_c10_1.py function batch_kron (line 15) | def batch_kron(A,B): function make_x_bar (line 27) | def make_x_bar(x,D,Lh): function execute_mm_lgm (line 45) | def execute_mm_lgm(x,Ns=2,n_iterations=20): function execute_mm_lgm_dereverb (line 107) | def execute_mm_lgm_dereverb(x,x_bar,Ns=2,n_iterations=20): function solver_inter_frequency_permutation (line 195) | def solver_inter_frequency_permutation(s_hat): function write_file_from_time_signal (line 245) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 270) | def calculate_snr(desired,out): FILE: section10/sample_code_c10_2.py function batch_kron (line 14) | def batch_kron(A,B): function make_x_bar (line 26) | def make_x_bar(x,D,Lh): function phi_multivariate_laplacian (line 42) | def phi_multivariate_laplacian(s_hat): function phi_laplacian (line 52) | def phi_laplacian(s_hat): function contrast_laplacian (line 60) | def contrast_laplacian(s_hat): function contrast_multivariate_laplacian (line 68) | def contrast_multivariate_laplacian(s_hat): function execute_ip_time_varying_gaussian_ilrma (line 81) | def execute_ip_time_varying_gaussian_ilrma(x,W,a,b,n_iterations=20): function execute_ip_time_varying_gaussian_ilrma_t (line 136) | def execute_ip_time_varying_gaussian_ilrma_t(x,x_bar,P,a,b,n_iterations=... function execute_ip_time_varying_gaussian_ilrma_dereverb (line 206) | def execute_ip_time_varying_gaussian_ilrma_dereverb(x,x_bar,W,a,b,n_iter... function projection_back (line 290) | def projection_back(s_hat,W): function write_file_from_time_signal (line 302) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 327) | def calculate_snr(desired,out): FILE: section11/sample_code_c11_1.py function phi_multivariate_laplacian (line 17) | def phi_multivariate_laplacian(s_hat): function phi_laplacian (line 27) | def phi_laplacian(s_hat): function contrast_laplacian (line 35) | def contrast_laplacian(s_hat): function contrast_multivariate_laplacian (line 43) | def contrast_multivariate_laplacian(s_hat): function execute_natural_gradient_ica (line 58) | def execute_natural_gradient_ica(x,W,phi_func=phi_laplacian,contrast_fun... function execute_em_lgm (line 101) | def execute_em_lgm(x,Ns=2,n_iterations=20): function execute_mm_lgm (line 160) | def execute_mm_lgm(x,Ns=2,n_iterations=20): function execute_ip_multivariate_laplacian_iva (line 221) | def execute_ip_multivariate_laplacian_iva(x,W,n_iterations=20): function execute_ip_time_varying_gaussian_ilrma (line 266) | def execute_ip_time_varying_gaussian_ilrma(x,W,a,b,n_iterations=20): function solver_inter_frequency_permutation (line 317) | def solver_inter_frequency_permutation(s_hat): function projection_back (line 367) | def projection_back(s_hat,W): function write_file_from_time_signal (line 379) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 404) | def calculate_snr(desired,out): FILE: section11/sample_code_c11_2.py function make_x_bar (line 19) | def make_x_bar(x,D,Lh): function dereverberation_ls (line 36) | def dereverberation_ls(x,x_bar): function dereverberation_wpe (line 63) | def dereverberation_wpe(x,x_bar,wpe_iterations=10): function write_file_from_time_signal (line 104) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 129) | def calculate_snr(desired,out): FILE: section3/sample_code_c3_9.py function batch_kron (line 8) | def batch_kron(A,B): FILE: section4/sample_code_c4_1.py function animation_update (line 98) | def animation_update(t): FILE: section6/sample_code_c6_1.py function calculate_steering_vector (line 11) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... FILE: section6/sample_code_c6_10.py function calculate_steering_vector (line 15) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 61) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_11.py function calculate_steering_vector (line 16) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 62) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_12.py function calculate_steering_vector (line 16) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 62) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_13.py function calculate_steering_vector (line 16) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 62) | def write_file_from_time_signal(signal,file_name,sample_rate): function execute_dsbf (line 88) | def execute_dsbf(x,a): function execute_mvdr (line 102) | def execute_mvdr(x,y,a): function execute_max_snr (line 127) | def execute_max_snr(x,y): function calculate_snr (line 160) | def calculate_snr(desired,out): function execute_mwf (line 177) | def execute_mwf(x,y,mu): FILE: section6/sample_code_c6_14.py function calculate_steering_vector (line 16) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 62) | def write_file_from_time_signal(signal,file_name,sample_rate): function execute_dsbf (line 88) | def execute_dsbf(x,a): function execute_mvdr (line 102) | def execute_mvdr(x,y,a): function execute_max_snr (line 127) | def execute_max_snr(x,y): function calculate_snr (line 160) | def calculate_snr(desired,out): function execute_mwf (line 177) | def execute_mwf(x,y,mu): FILE: section6/sample_code_c6_2.py function calculate_steering_vector (line 15) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 61) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_3.py function calculate_steering_vector (line 15) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 61) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_4.py function calculate_steering_vector (line 15) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 61) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_5.py function calculate_steering_vector (line 15) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 61) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_6.py function calculate_steering_vector (line 14) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... FILE: section6/sample_code_c6_7.py function calculate_steering_vector (line 14) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... FILE: section6/sample_code_c6_8.py function calculate_steering_vector (line 15) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 61) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section6/sample_code_c6_9.py function calculate_steering_vector (line 15) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function write_file_from_time_signal (line 61) | def write_file_from_time_signal(signal,file_name,sample_rate): FILE: section7/sample_code_c7_1.py function write_file_from_time_signal (line 15) | def write_file_from_time_signal(signal,file_name,sample_rate): function execute_two_microphone_sparse_separation (line 43) | def execute_two_microphone_sparse_separation(x_left,x_right,is_use_ampli... function calculate_snr (line 67) | def calculate_snr(desired,out): FILE: section7/sample_code_c7_2.py function write_file_from_time_signal (line 15) | def write_file_from_time_signal(signal,file_name,sample_rate): function execute_two_microphone_sparse_separation (line 43) | def execute_two_microphone_sparse_separation(x_left,x_right,is_use_ampli... function calculate_snr (line 67) | def calculate_snr(desired,out): FILE: section7/sample_code_c7_3.py function write_file_from_time_signal (line 15) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_steering_vector (line 45) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function execute_doa_sparse_separation (line 93) | def execute_doa_sparse_separation(input_vectors,steering_vectors,omega): function calculate_snr (line 112) | def calculate_snr(desired,out): function modify_angle_diff (line 243) | def modify_angle_diff(diff): FILE: section7/sample_code_c7_4.py function write_file_from_time_signal (line 15) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_steering_vector (line 45) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function estimate_steering_vector (line 90) | def estimate_steering_vector(Rs): function estimate_covariance_matrix (line 101) | def estimate_covariance_matrix(x,mask): function execute_sparse (line 130) | def execute_sparse(x,mask): function execute_mwf (line 143) | def execute_mwf(x,Rn,Rs): function execute_dsbf (line 160) | def execute_dsbf(x,a): function execute_mvdr (line 175) | def execute_mvdr(x,Rn,a): function execute_mvdr2 (line 198) | def execute_mvdr2(x,Rn,Rs): function execute_max_snr (line 218) | def execute_max_snr(x,Rn,Rs): function estimate_mask (line 250) | def estimate_mask(input_vectors,steering_vectors,omega): function calculate_snr (line 267) | def calculate_snr(desired,out): function modify_angle_diff (line 405) | def modify_angle_diff(diff): FILE: section7/sample_code_c7_5.py function write_file_from_time_signal (line 15) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_steering_vector (line 45) | def calculate_steering_vector(mic_alignments,source_locations,freqs,soun... function estimate_steering_vector (line 90) | def estimate_steering_vector(Rs): function estimate_covariance_matrix (line 101) | def estimate_covariance_matrix(x,mask): function execute_sparse (line 130) | def execute_sparse(x,mask): function execute_mwf (line 143) | def execute_mwf(x,Rn,Rs): function execute_dsbf (line 160) | def execute_dsbf(x,a): function execute_mvdr (line 175) | def execute_mvdr(x,Rn,a): function execute_mvdr2 (line 198) | def execute_mvdr2(x,Rn,Rs): function execute_max_snr (line 218) | def execute_max_snr(x,Rn,Rs): function estimate_mask (line 250) | def estimate_mask(input_vectors,steering_vectors,omega): function calculate_snr (line 267) | def calculate_snr(desired,out): function modify_angle_diff (line 405) | def modify_angle_diff(diff): FILE: section8/sample_code_c8_1.py function phi_laplacian (line 17) | def phi_laplacian(s_hat): function contrast_laplacian (line 25) | def contrast_laplacian(s_hat): function execute_natural_gradient_ica (line 40) | def execute_natural_gradient_ica(x,W,phi_func=phi_laplacian,contrast_fun... function solver_inter_frequency_permutation (line 81) | def solver_inter_frequency_permutation(s_hat): function projection_back (line 131) | def projection_back(s_hat,W): function write_file_from_time_signal (line 143) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 168) | def calculate_snr(desired,out): FILE: section8/sample_code_c8_2.py function phi_multivariate_laplacian (line 16) | def phi_multivariate_laplacian(s_hat): function phi_laplacian (line 26) | def phi_laplacian(s_hat): function contrast_laplacian (line 34) | def contrast_laplacian(s_hat): function contrast_multivariate_laplacian (line 42) | def contrast_multivariate_laplacian(s_hat): function execute_natural_gradient_ica (line 57) | def execute_natural_gradient_ica(x,W,phi_func=phi_laplacian,contrast_fun... function execute_ip_multivariate_laplacian_iva (line 100) | def execute_ip_multivariate_laplacian_iva(x,W,n_iterations=20): function solver_inter_frequency_permutation (line 141) | def solver_inter_frequency_permutation(s_hat): function projection_back (line 191) | def projection_back(s_hat,W): function write_file_from_time_signal (line 203) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 228) | def calculate_snr(desired,out): FILE: section8/sample_code_c8_3.py function phi_multivariate_laplacian (line 17) | def phi_multivariate_laplacian(s_hat): function phi_laplacian (line 27) | def phi_laplacian(s_hat): function contrast_laplacian (line 35) | def contrast_laplacian(s_hat): function contrast_multivariate_laplacian (line 43) | def contrast_multivariate_laplacian(s_hat): function execute_natural_gradient_ica (line 58) | def execute_natural_gradient_ica(x,W,phi_func=phi_laplacian,contrast_fun... function execute_ip_multivariate_laplacian_iva (line 101) | def execute_ip_multivariate_laplacian_iva(x,W,n_iterations=20): function execute_ip_time_varying_gaussian_ilrma (line 146) | def execute_ip_time_varying_gaussian_ilrma(x,W,a,b,n_iterations=20): function solver_inter_frequency_permutation (line 197) | def solver_inter_frequency_permutation(s_hat): function projection_back (line 247) | def projection_back(s_hat,W): function write_file_from_time_signal (line 259) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 284) | def calculate_snr(desired,out): FILE: section8/sample_code_c8_4.py function phi_multivariate_laplacian (line 17) | def phi_multivariate_laplacian(s_hat): function phi_laplacian (line 27) | def phi_laplacian(s_hat): function contrast_laplacian (line 35) | def contrast_laplacian(s_hat): function contrast_multivariate_laplacian (line 43) | def contrast_multivariate_laplacian(s_hat): function execute_natural_gradient_ica (line 58) | def execute_natural_gradient_ica(x,W,phi_func=phi_laplacian,contrast_fun... function execute_em_lgm (line 101) | def execute_em_lgm(x,Ns=2,n_iterations=20): function execute_mm_lgm (line 162) | def execute_mm_lgm(x,Ns=2,n_iterations=20): function execute_ip_multivariate_laplacian_iva (line 223) | def execute_ip_multivariate_laplacian_iva(x,W,n_iterations=20): function execute_ip_time_varying_gaussian_ilrma (line 268) | def execute_ip_time_varying_gaussian_ilrma(x,W,a,b,n_iterations=20): function solver_inter_frequency_permutation (line 319) | def solver_inter_frequency_permutation(s_hat): function projection_back (line 369) | def projection_back(s_hat,W): function write_file_from_time_signal (line 381) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 406) | def calculate_snr(desired,out): FILE: section9/sample_code_c9_1.py function make_x_bar (line 16) | def make_x_bar(x,D,Lh): function dereverberation_ls (line 33) | def dereverberation_ls(x,x_bar): function write_file_from_time_signal (line 60) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 85) | def calculate_snr(desired,out): FILE: section9/sample_code_c9_2.py function make_x_bar (line 16) | def make_x_bar(x,D,Lh): function dereverberation_ls (line 33) | def dereverberation_ls(x,x_bar): function dereverberation_wpe (line 60) | def dereverberation_wpe(x,x_bar,wpe_iterations=10): function write_file_from_time_signal (line 101) | def write_file_from_time_signal(signal,file_name,sample_rate): function calculate_snr (line 126) | def calculate_snr(desired,out):
Condensed preview — 74 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (433K chars).
[
{
"path": "LICENSE.txt",
"chars": 1091,
"preview": "MIT License\r\n\r\nCopyright (c) 2020 Masahito Togami\r\n\r\nPermission is hereby granted, free of charge, to any person obtaini"
},
{
"path": "README.md",
"chars": 1267,
"preview": "## Pythonで学ぶ音源分離(機械学習実践シリーズ)のソースコード\n\n\n\n* [ILRMAに基づく音源分離と\n残響除去の統合的最適化法](section1"
},
{
"path": "section11/sample_code_c11_1.py",
"chars": 26829,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section11/sample_code_c11_2.py",
"chars": 7968,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section11.md",
"chars": 133,
"preview": "\n## 第11章のサンプルコード\n\n* [pyroomacousticsによる音源分離技術](section11/sample_code_c11_1.py)\n* [NARA-WPEを用いた残響除去](section11/sample_cod"
},
{
"path": "section2/sample_code_c2_1.py",
"chars": 812,
"preview": "\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#pyroomacousticsをインポート (ここではデータセットをダウンロードするために使用)\r\nimpor"
},
{
"path": "section2/sample_code_c2_10.py",
"chars": 1044,
"preview": "\r\n\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy "
},
{
"path": "section2/sample_code_c2_11.py",
"chars": 978,
"preview": "\r\n\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy "
},
{
"path": "section2/sample_code_c2_12.py",
"chars": 976,
"preview": "\r\n\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy "
},
{
"path": "section2/sample_code_c2_13.py",
"chars": 3562,
"preview": "\r\n\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy "
},
{
"path": "section2/sample_code_c2_14.py",
"chars": 3580,
"preview": "\r\n\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy "
},
{
"path": "section2/sample_code_c2_2.py",
"chars": 838,
"preview": "\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy as"
},
{
"path": "section2/sample_code_c2_3.py",
"chars": 501,
"preview": "\r\n\r\nimport wave as wave\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\n#白色雑音のサンプル数を設定\r\nn_sample=40000\r\n\r\n#サンプリン"
},
{
"path": "section2/sample_code_c2_4.py",
"chars": 673,
"preview": "\r\n\r\nimport wave as wave\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\n#白色雑音のサンプル数を設定\r\nn_sample=40000\r\n\r\n#サンプリン"
},
{
"path": "section2/sample_code_c2_5.py",
"chars": 601,
"preview": "\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy as"
},
{
"path": "section2/sample_code_c2_6.py",
"chars": 872,
"preview": "\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy as"
},
{
"path": "section2/sample_code_c2_7.py",
"chars": 439,
"preview": "\r\n#numpyをインポート\r\nimport numpy as np\r\n\r\n#複素数データを定義する\r\nz=1.0+2.0j\r\nu=2.0+3.0j\r\n\r\n#複素数を表示する\r\nprint(\"z=\",z)\r\n\r\nprint(\"u=\",u)\r"
},
{
"path": "section2/sample_code_c2_8.py",
"chars": 733,
"preview": "\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy as"
},
{
"path": "section2/sample_code_c2_9.py",
"chars": 846,
"preview": "\r\n#wave形式の音声波形を読み込むためのモジュール(wave)をインポート\r\nimport wave as wave\r\n\r\n#numpyをインポート(波形データを2byteの数値列に変換するために使用)\r\nimport numpy as"
},
{
"path": "section2.md",
"chars": 761,
"preview": "\n## 第2章のサンプルコード\n\n* [音声ファイルを開く](section2/sample_code_c2_1.py)\n* [音声ファイルをグラフ化する](section2/sample_code_c2_2.py)\n* [白色雑音をグラフ"
},
{
"path": "section3/sample_code_c3_1.py",
"chars": 1007,
"preview": "\r\n\n#numpyをインポート(行列を扱う各種関数を含む)\nimport numpy as np\n\n#行列を定義\nA=np.matrix([[3.,1.,2.],[2.,3.,1.]])\n\n#行列の大きさを表示\nprint(\"行列Aの大きさ"
},
{
"path": "section3/sample_code_c3_2.py",
"chars": 1131,
"preview": "\r\n\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#乱数の種を設定\r\nnp.random.seed(0)\r\n\r\n#テンソルの大きさを設定\r\nL=10\r\nK=5\r\nM=3\r\nR=3\r\n"
},
{
"path": "section3/sample_code_c3_3.py",
"chars": 776,
"preview": "\r\n\n#numpyをインポート(行列を扱う各種関数を含む)\nimport numpy as np\n\r\n#乱数の種を設定\r\nnp.random.seed(0)\r\n\n#テンソルの大きさを設定\r\nL=10\r\nK=5\r\nM=3\r\nR=3\r\nS=3\r"
},
{
"path": "section3/sample_code_c3_4.py",
"chars": 806,
"preview": "\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#乱数の種を設定\r\nnp.random.seed(0)\r\n\r\n#行列の大きさを設定する\r\nL=10\r\nM=3\r\nN=3\r\n#ランダムな複"
},
{
"path": "section3/sample_code_c3_5.py",
"chars": 241,
"preview": "\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#行列を定義\r\nA=np.matrix([[3.,1.,2.],[2.,3.,1.]])\r\n\r\n#ベクトルを定義\r\nb=np.array"
},
{
"path": "section3/sample_code_c3_6.py",
"chars": 265,
"preview": "\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#行列を定義\r\na=np.matrix([3.+2.j,1.-1.j,2.+2.j])\r\n\r\n#ベクトルを定義\r\nb=np.array("
},
{
"path": "section3/sample_code_c3_7.py",
"chars": 677,
"preview": "\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#乱数の種を設定\r\nnp.random.seed(0)\r\n\r\n#行列の大きさを設定する\r\nL=10\r\nM=3\r\nN=3\r\n#ランダムな複"
},
{
"path": "section3/sample_code_c3_8.py",
"chars": 665,
"preview": "\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#乱数の種を設定\r\nnp.random.seed(0)\r\n\r\n#行列の大きさを設定する\r\nL=10\r\nM=3\r\nN=3\r\n#ランダムな複"
},
{
"path": "section3/sample_code_c3_9.py",
"chars": 1903,
"preview": "\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#A: ...mn\r\n#B: ...ij\r\n#AとBの最後の二軸以外の次元は一致していることを前提とする\r\ndef batch_kron"
},
{
"path": "section3.md",
"chars": 448,
"preview": "\n## 第3章のサンプルコード\n\n* [行列の基本的な演算](section3/sample_code_c3_1.py)\n* [アインシュタイン縮約記法を用いたテンソル計算](section3/sample_code_c3_2.py)\n* "
},
{
"path": "section4/sample_code_c4_1.py",
"chars": 3158,
"preview": "\r\n#numpyをインポート(行列を扱う各種関数を含む)\r\nimport numpy as np\r\n\r\n#可視化のためにmatplotlibモジュールをインポート\r\nimport matplotlib.pyplot as plt\r\n\r\n#ア"
},
{
"path": "section4.md",
"chars": 83,
"preview": "\n## 第4章のサンプルコード\n\n* [(参考)EMアルゴリズムによる混合ガウス分布のパラメータ最適化](section4/sample_code_c4_1.py)\n"
},
{
"path": "section5/sample_code_c5_1.py",
"chars": 928,
"preview": "\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as signal\r\n\r\n#乱数の種を初期化\r\nnp."
},
{
"path": "section5/sample_code_c5_2.py",
"chars": 2571,
"preview": "\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\n\r\n#乱数の種を初期化\r\nnp.random.seed(0)\r\n\r\n#畳み込みに用いる音声波形"
},
{
"path": "section5/sample_code_c5_3.py",
"chars": 2579,
"preview": "\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\n\r\n#乱数の種を初期化\r\nnp.random.seed(0)\r\n\r\n#畳み込みに用いる音声波形"
},
{
"path": "section5/sample_code_c5_4.py",
"chars": 2598,
"preview": "\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\n\r\n#乱数の種を初期化\r\nnp.random.seed(0)\r\n\r\n#畳み込みに用いる音声波形"
},
{
"path": "section5/sample_code_c5_5.py",
"chars": 2604,
"preview": "\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\n\r\n#乱数の種を初期化\r\nnp.random.seed(0)\r\n\r\n#畳み込みに用いる音声波形"
},
{
"path": "section5/sample_code_c5_6.py",
"chars": 2960,
"preview": "\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\n#乱数の種を初期化\r\nn"
},
{
"path": "section5/sample_code_c5_7.py",
"chars": 2965,
"preview": "\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\n#乱数の種を初期化\r\nn"
},
{
"path": "section5.md",
"chars": 404,
"preview": "## 第5章のサンプルコード\n\n* [インパルス応答の畳み込みの例](section5/sample_code_c5_1.py)\n* [Pyroomacousticsを用いた室内伝達関数のシミュレーションと畳み込み](section5/sa"
},
{
"path": "section6/sample_code_c6_1.py",
"chars": 2756,
"preview": "\r\nimport numpy as np\r\n\r\n#ステアリングベクトルを算出\r\n#mic_position: 3 x M dimensional ndarray [[x,y,z],[x,y,z]]\r\n#source_position: 3"
},
{
"path": "section6/sample_code_c6_10.py",
"chars": 5728,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\n\r\n#ステアリングベクトルを算出\r\n"
},
{
"path": "section6/sample_code_c6_11.py",
"chars": 5873,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section6/sample_code_c6_12.py",
"chars": 5723,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section6/sample_code_c6_13.py",
"chars": 11154,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section6/sample_code_c6_14.py",
"chars": 11154,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section6/sample_code_c6_2.py",
"chars": 5096,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\n\r\n#ステアリングベクトルを算出\r\n"
},
{
"path": "section6/sample_code_c6_3.py",
"chars": 5105,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\n\r\n#ステアリングベクトルを算出\r\n"
},
{
"path": "section6/sample_code_c6_4.py",
"chars": 5184,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\n\r\n#ステアリングベクトルを算出\r\n"
},
{
"path": "section6/sample_code_c6_5.py",
"chars": 5236,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\n\r\n#ステアリングベクトルを算出\r\n"
},
{
"path": "section6/sample_code_c6_6.py",
"chars": 3780,
"preview": "\r\n\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport matplotlib.pyplot as plt\r\n\r\n#ステアリングベクトルを算出\r\n#mic_position: 3 x"
},
{
"path": "section6/sample_code_c6_7.py",
"chars": 3783,
"preview": "\r\n\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport matplotlib.pyplot as plt\r\n\r\n#ステアリングベクトルを算出\r\n#mic_position: 3 x"
},
{
"path": "section6/sample_code_c6_8.py",
"chars": 5493,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\n\r\n#ステアリングベクトルを算出\r\n"
},
{
"path": "section6/sample_code_c6_9.py",
"chars": 5602,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\n\r\n#ステアリングベクトルを算出\r\n"
},
{
"path": "section6.md",
"chars": 869,
"preview": "## 第6章のサンプルコード\n\n* [Far/Nearの両方に対応したステアリングベクトル計算コード](section6/sample_code_c6_1.py)\n* [遅延和アレイによる雑音抑圧](section6/sample_code"
},
{
"path": "section7/sample_code_c7_1.py",
"chars": 7020,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section7/sample_code_c7_2.py",
"chars": 7044,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section7/sample_code_c7_3.py",
"chars": 9155,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section7/sample_code_c7_4.py",
"chars": 16348,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section7/sample_code_c7_5.py",
"chars": 16508,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section7.md",
"chars": 312,
"preview": "## 第7章のサンプルコード\n\n* [音声のスパース性に基づく音源分離](section7/sample_code_c7_1.py)\n* [音声のスパース性に基づく音源分離(マイクロホンの間隔40センチ)](section7/sample_"
},
{
"path": "section8/sample_code_c8_1.py",
"chars": 10451,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section8/sample_code_c8_2.py",
"chars": 14459,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section8/sample_code_c8_3.py",
"chars": 17578,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section8/sample_code_c8_4.py",
"chars": 23689,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section8.md",
"chars": 253,
"preview": "\n## 第8章のサンプルコード\n\n* [自然勾配法に基づく独立成分分析と周波数間パーミュテーション解法、およびプ\nロジェクションバックの実行コード](section8/sample_code_c8_1.py)\n* [IP法に基づく独立ベクト"
},
{
"path": "section9/sample_code_c9_1.py",
"chars": 6155,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section9/sample_code_c9_2.py",
"chars": 7761,
"preview": "\r\n\r\nimport wave as wave\r\nimport pyroomacoustics as pa\r\nimport numpy as np\r\nimport scipy.signal as sp\r\nimport scipy as sc"
},
{
"path": "section9.md",
"chars": 109,
"preview": "\n## 第9章のサンプルコード\n\n* [最小二乗法による残響除去](section9/sample_code_c9_1.py)\n* [WPEによる残響除去](section9/sample_code_c9_2.py)\n"
}
]
About this extraction
This page contains the full source code of the masahitotogami/python_source_separation GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 74 files (331.5 KB), approximately 126.9k tokens, and a symbol index with 161 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.