Translate

2019年9月25日水曜日

◆Windows10のSpatial Soundの効果を視覚化:Windows Sonic for Headphones、Dolby Atmos for Headphones、2ch_Stereoのスペクトル解析の比較です:テストトーンの録音データ分析:付録は音声データ解析用の「Rコード」です

 Windows10のSpatial Sound(立体音響)の効果を視覚化してみました。

 今回は、7.1.2チャンネルのテストトーンの録音データについて、Windows Sonic for Headphones、Dolby Atmos for Headphones、2ch_Stereoの3通りの録音データのスペクトル解析の形状を比較しています。



 グラフは、Leftチャンネルに録音された、各スピーカーのテストトーンの音声のスペクトル解析の結果です。横軸が音声の周波数で、縦軸が音声のレベルです。

 Windows Sonic for HeadphonesやDolby Atmos for Headphonesが「オフ」の状態で録音したデータ(2ch_Stereo)は、周波数帯別のレベルの凹凸がありません。

 Windows Sonic for HeadphonesやDolby Atmos for Headphonesを「オン」の状態で録音したデータでは、周波数帯別のレベルの凹凸が見られます。

 この凹凸の特徴から、Windows Sonic for HeadphonesやDolby Atmos for Headphonesが、頭部伝達関数(HRTF)を利用して音声処理をしていることがうかがえます。

 また、Windows Sonic for HeadphonesやDolby Atmos for Headphonesが「オフ」の状態で録音した「サイドレフト」「バックレフト」「トップレフト」の録音データのレベルがかなり低いことがわかります。
 
Leftチャンネルに録音した「フロントレフト」スピーカーのテストトーンの特徴

Leftチャンネルに録音した「センター」スピーカーのテストトーンの特徴

Leftチャンネルに録音した「サイドレフト」スピーカーのテストトーンの特徴

Leftチャンネルに録音した「バックレフト」スピーカーのテストトーンの特徴

Leftチャンネルに録音した「トップレフト」スピーカーのテストトーンの特徴

----------------------------------------------------------------
【付録:音声データ解析用の「R」のコードです】
 分析のための「R」のコードが整備できてきたので、3通りの録音データの特徴を一つの図の中でグラフ化することができるようになりました。

 当初、「meanspec()」の設定を「dB = 'max0'」としていたので、音声レベルの絶対値の比較ではなく、形状の比較になっていました。この設定の場合、解析対象の録音データそれぞれの音声レベルの最大値が0となるので、異なる録音データのレベルを相互に比較することができません。

 その後、「meanspec()」の設定を「norm=FALSE」にする方法がわかったので、音声レベルの相互比較ができるようになりました。そして、低音域の差が極端に大きくなっていたので、音声レベルのy軸をlogスケールにすることによって、中高音域でもレベル差の比較がわかりやすいようにしています。

 最初は、Audacityで録音したデータのスペクトル解析結果を書き出して、Excelで読み込んで、というように手動でデータ処理をしていましたが、「手動の作業」をできるだけ排除するために、「R」コードを利用することにしました。「R」で音声データを直接分析できるので、とても便利です。

 でも、Audacityのスペクトル解析のグラフはとても見やすいので、Audacityなども活用していきたいと思います。Audacityのスペクトル解析結果の数字で、音声レベルの相互比較ができます。

 「R」コードでの処理には、Excelシートでのデータ処理のように、データの手作業でのコピペなどは一切ありません。「R」コードでの処理は、再現性、反復性、信頼性の高い方法だと思います。ただし、「R」での処理では、データの全体を一覧しづらいというか、一覧しなくても処理できてしまう点には注意が必要だと思います。

 ドルビー社の7.1.2チャンネルのテストトーンには、各スピーカーごとに60秒間のテストトーン音声があります。そこで、「for i」文のループを利用して、 録音データから60秒おきに各スピーカーの5秒間の音声データを抜き取って、スペクトル解析をしています。グラフの作成でも「for i」文のループを利用しています。


【Rコードの処理フロー】

録音データの読み込み → 3通りの録音ファイルごとに10個のスピーカーそれぞれのデータのスペクトル解析 → 3通りの録音ファイルの解析結果データの結合 → 10個のスピーカーそれぞれの解析結果グラフの作成


library(soundgen)
library(seewave)
library(tuneR)
library(ggplot2)
library(tidyr)
library(dplyr)

###録音対象のスピーカーの名前の対応表を作成
sptrans <- data.frame(Speaker = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  SPNAME = c("Front Left", "Front Right", "Center", "Subwoofer", "Side Left", "Side Right", "Back Left", "Back Right", "Top Left", "Top Right")
)

###録音データの読み込み
wdat <- readWave("712winsonic.wav")

###左右のチャンネルの録音データをそれぞれ抽出
wdatL<-channel(wdat,"left")
wdatR<-channel(wdat,"right")

###テストトーンの5秒間のデータを抽出するための開始・終了秒を指定
st <- 5
et <- 10
df_lr <- NULL
i = 0


###10個のスピーカーのそれぞれについて、スペクトル解析を行う
for(i in 1:10){

###左チャンネルの録音データのスペクトル解析
 d_l <- meanspec(wdatL,from=st,to=et, f = 48000,norm=FALSE,correction = "energy", flim = c(0, 20), col="blue")
 colnames(d_l) <- c("Frequency1", "dB_L")

###右チャンネルの録音データのスペクトル解析
 d_r <- meanspec(wdatR,from=st,to=et, f = 48000, norm=FALSE,correction = "energy", flim = c(0, 20), col="red")
 colnames(d_r) <- c("Frequency", "dB_R")

 d_lr <- cbind(d_l,d_r)
 d_lr <- as.data.frame(d_lr)

###解析結果データにスピーカー番号と音声ファイル情報を付与
 d_lr$Speaker <- as.integer(i)
 d_lr$Sound_File <- as.character("WinSonic")

 df_lr <- rbind(df_lr,d_lr)

###60秒後の次のスピーカーの音声を解析するために、60をプラス
 st <- st + 60
 et <- et + 60
}

###Windows Sonic for Headphonesの解析データとして格納
wdf_lr <- df_lr


###同様にDolby Atmos for Headphonesと2chステレオ音声の解析を行う
ddat <- readWave("712dolby.wav")
ddatL<-channel(ddat,"left")
ddatR<-channel(ddat,"right")
st <- 5
et <- 10
df_lr <- NULL
i=0
for(i in 1:10){
d_l <- meanspec(ddatL,from=st,to=et, f = 48000, norm=FALSE,correction = "energy", flim = c(0, 20), col="blue")
colnames(d_l) <- c("Frequency1", "dB_L")

d_r <- meanspec(ddatR,from=st,to=et, f = 48000, norm=FALSE,correction = "energy", flim = c(0, 20), col="red")
colnames(d_r) <- c("Frequency", "dB_R")

d_lr <- cbind(d_l,d_r)
d_lr <- as.data.frame(d_lr)
d_lr$Speaker <- as.integer(i)
d_lr$Sound_File <- as.character("DolbyAtmos")
df_lr <- rbind(df_lr,d_lr)
st <- st + 60
et <- et + 60
}

###Dolby Atmos for Headphonesの解析データとして格納
ddf_lr <- df_lr


sdat <- readWave("712stereo.wav")
sdatL<-channel(sdat,"left")
sdatR<-channel(sdat,"right")
st <- 5
et <- 10
df_lr <- NULL
i=0

for(i in 1:10){
d_l <- meanspec(sdatL,from=st,to=et, f = 48000, norm=FALSE,correction = "energy", flim = c(0, 20), col="blue")
colnames(d_l) <- c("Frequency1", "dB_L")

d_r <- meanspec(sdatR,from=st,to=et, f = 48000, norm=FALSE,correction = "energy", flim = c(0, 20), col="red")
colnames(d_r) <- c("Frequency", "dB_R")

d_lr <- cbind(d_l,d_r)
d_lr <- as.data.frame(d_lr)
d_lr$Speaker <- as.integer(i)
d_lr$Sound_File <- as.character("2ch_Stereo")
df_lr <- rbind(df_lr,d_lr)
st <- st + 60
et <- et + 60
}

###2ch_Stereoの解析データとして格納
sdf_lr <- df_lr

###3通りの解析データを結合する
swddf_lr <- rbind(wdf_lr,ddf_lr,sdf_lr)



###10個のスピーカーの解析データのグラフ作成(レフト、ライトのチャンネル別)

for(i in 1:10){

###グラフ作成用データの整備。必要な列(変数)をスピーカーごとに集める
 td_lr <-select(swddf_lr,Frequency,dB_L,dB_R,Sound_File,Speaker) %>% 
  filter(Speaker == i)

###「スピーカー番号とスピーカー名の対応表」からスピーカー名を入手する
 swddf_lr1 <- join(td_lr,sptrans,by="Speaker")

 swddf_lr1$SPNAME <-as.character(swddf_lr1$SPNAME)

###レフトチャンネルのグラフ作成

g <- ggplot(data = swddf_lr1) + geom_line(aes(x=Frequency,y=dB_L,group=Sound_File, colour=Sound_File)) + labs(x="Frequency(kHz)",y="Energy(log2)") + labs(title="Left Speaker") + scale_y_continuous(trans = 'log2')
g1 <-  g + facet_wrap(~SPNAME)
ggsave(file=paste0("cgl",i,".png"),plot(g1),dpi = 200, width = 7.2, height = 4.8)
print(g1)


###ライトチャンネルのグラフ作成

g <- ggplot(data = swddf_lr1) +
geom_line(aes(x=Frequency,y=dB_R,group=Sound_File, colour=Sound_File)) + labs(x="Frequency(kHz)",y="Energy(log2)") + labs(title="Right Speaker") + scale_y_continuous(trans = 'log2')
g2 <-  g + facet_wrap(~SPNAME)
ggsave(file=paste0("cgr",i,".png"),plot(g1),dpi = 200, width = 7.2, height = 4.8)
print(g2)
}




----------------------------------------------------------------


0 件のコメント:

コメントを投稿