フレーム独立GMM-based mappingによる声質変換

こんにちは。1年のSannkoです。AI班です。

初投稿になります。

宜しくお願いします。

 

UMUさんの記事にもありますが、AI班は声質変換の活動をしています。

まだどのような手法で声質変換をしていくかは検討中ですが、既存の手法を試してみようと思います。

 

戸田さんの論文の2章に書いてある、提案手法ではない古い手法をやってみます。

この手法ではフレームごとにGMMでソースとターゲットの同時分布を推定して、そこから条件付き確率やら周辺確率が出せるのでそれを使って変換を行います。

フレーム間の関係は全く考えられていないので、最近の手法と比べるとかなり古典的な手法ですね。

 

https://pdfs.semanticscholar.org/d419/ceb2753232373fd4ab9534b371e017cd9dc1.pdf

 

データはこのサイトのものを使わせてもらいました。

ありがたいですね、こういう研究室は。

8.00モーラ/秒の25文のデータを使っています。

 

http://www.it.ice.uec.ac.jp/SRV-DB/

 

女性1から男性への変換をやってみたいと思います。

変換元の女性の声はこれ

 

 

ターゲットはこの男性です。

 

 

この文章のデータは訓練データからは除いてあります。

変換を行った結果がこれです。

基本周波数はそのままなので、声が高くなっているのがわかります。

ただ、声質は男性のものに近くなっている気がしますね(定性的)。

 

 

基本周波数の変換についてはフィルタとの関係などを考えてきちんと検討すべきですが、(正直よく分からないので)今回はとりあえず単純に切片0の回帰曲線でモデル化しました。

単純ですが、画像をみるとわかる通り、それなりに妥当です(定性的2)。

(追記)貼ってから気づいたんですが、この画像は切片を0にする前のやつでした。下のデータに使ったモデルはちゃんと切片0になっています。

figure_1-%e3%81%ae%e3%82%b3%e3%83%94%e3%83%bc

このモデルを使って基本周波数も変換をした結果がこれです。

ピッチを適当に扱ったのでノイズが増えてしまったような気がします(定性的3)。

しかしかなりターゲットの声に近づいたと思います(定性的4)。

 

 

正直、この単純な手法でここまで変換できたので驚いています。

今後は戸田さんの提案手法など、もう少し高度な手法を試してみたいですね。

音声分析合成システムWORLDをPythonに移植した

最近,音声の声質変換を行うために,Pythonで使えるライブラリを探していました.matlab上で使える便利な音声分析合成ソフトとして「WORLD」が存在しますが,これをPython上で使おうとすると少々めんどくさいということがありました.そこで,科学研究用のスタンダードなPython開発環境Anacondaがあれば簡単にWORLDを使えるように,matlabのコードを参考にPythonへ完全移植を行っています.とりあえず,基本的な分析→合成までの部分の移植が完了したので,移植したコードがまともに動くかどうかの検証も含めて記事にしてみました.

 

まずは,元の音声データです.この音声データをもとに,パラメータを抽出(分析)し,さらに再合成することで音声データが再構築されます.再構築する際に,パラメータを統計的に変化させて別人の声を生成する方法が,「統計的声質変換」です.

 

次に,正規版(matlab)の変換結果です.

 

最後に,移植版(Python)の変換結果です.

 

聞いてみると,正規版と移植版の違いが分かると思いますが,これは,matlab版で使用されている一部の関数が,pythonでは存在しないために,なるべく同じような挙動をするようにコードを書いていますが,やや違いがでてきてしまうためです.

なお,この移植版を公開していいかわからないため,公開するかどうかは後日決定します.

今後,移植を完成させつつ,声質変換についての記事も書いていこうと思います.BYE!

 

 

–ここから残念なお話–

まず,matlabからpythonに移植するとき,配列のインデックスの書き方の違いで,とても混乱した.matlabでは,配列のはじめは1から始まるが,Pythonでは一般的な言語と同じく0である.これだけなら,数値を1ずらすだけでいいのだが(実際にはそれだけでもかなりのストレスである.),配列から一部の列を取り出す際,例えば,[0,1,2,3,4,5]という配列から[2,3,4]を取り出すとき,取り出しの記述はPythonでは2:5(2番目から5番目の意)となり,Matlabでは3:5(3番目から5番目の意)とかく(Pythonでは,一番最後のインデックスは無視される.)これが非常に頭を混乱させる要因となっており,一番混乱したときは,matlabのコードを実行したときの図を紙に書いて,紙に書かれた内容をPythonコードで書くという所業をしてしまった.

さらに,面倒くさいのが,matlabで定義されている関数を,pythonで移植する場合,matlabの関数となるべく近い挙動をするpythonコードを書く必要がある.pythonで完全一致する関数があればいいのだが(うれしいことに,汎用的なものは共通化されているようだ),すべてきれいに一致するとは限らないので,なるべく同じ計算結果となるようにコードを書く必要があった.

一部は,面倒くさいので放置しているが,聞こえ上は似ているものができたので,まずは良しとすることにした.

 

LOGSPECTROGRAMさむねいる

テクノポップチックな曲づくり ~Ocean~

こんにちは、音楽班のGMAです。やたらめったら暑い日が続いてますね。

sound cloudに曲をアップしました。今回はそれの紹介です。

Ocean Short Version
作詞作曲 : GMA 歌 : IA

今回の曲はテクノポップチックなことをしようと思って作った実験作です。

トラックはこんな感じ。
どん。(整理されてなくてスミマセン……(;´Д`))

スクリーンショット (87)

自分はどちらかというとトラック少なめのシンプルな曲が好きなのですが、やっぱり打ち込みらしい曲はトラックが多くなりますね。今回の曲のキモは、

・ケロケロボイス
・サビ前の盛り上げ
・MS処理

といったところです(ほんとはまだまだあるのですが)。

まず、ケロケロボイスですが、ケロケロボイスってのは、Perfumeとかでお馴染みの機械的なボイスです。人間は歌うときに音程と音程の間を滑らかにつなぎますが、これを無理矢理、急激に音程に変わるように補正してやると独特な声になります。今回はボーカロイドに歌わせていますので、ある程度既に機械的なところはあるんですが、ガンガン補正させるためにあえて音を外したりしています。

サビ前の盛り上げはテクノなどの電子音楽でよくやる常套手段を使ってます。スネアドラムの連打や、ノイズにフィルタをかけて作るシュワシュワした音、そして、思いっきりリバーブ(反響音とかの効果のことです)を掛けたクラップ。この部分は他の部分に比べるとかなり慎重に調整しています。

MS処理は音をMidとSideに分け(音楽は普段はLRで扱うことが多いです)、Sideを強調することで広がりのある音にする手法です。音圧稼ぎの常套手段でもありますが、現代的な電子音楽感を出すのにうってつけな方法でもあります。

というわけで、本日はここまで。

それでは、また。

セルフライナーノーツ ~Dots~

どもです、音楽班のGMAです。

記事タイトルからして研究ネタが多いKCSらしからぬ感じですが、sound cloudに新曲をアップしましたので、そちらについてライナーノーツ的なものを書こうかと思います。

ちなみにさりげなく告知ですが、今年は矢上祭や三田祭などで、音楽班のCDを販売予定です。この新曲もそのCDからの曲となります。

Dots Short Version
作詞作曲 : GMA 歌 : IA

この曲は今年の2月ごろに作曲した曲で、「16ビートでアイデンティティがテーマ」という出発点からイメージを膨らませていきました。だいぶ以前からアイデンティティ(=自己同一性、自分が自分であること)については、いつか曲を書いてみたいなと思っていたので、念願叶ったり、という感じです。(なお、サビとかイントロが一応16ビートですね。)

自分が自分であることを確かめるってのは意外と難しい話だと思うんです。なぜなら、「自己同一性」という言葉には「同一」というワードが入っていますが、厳密に言えば、一時として自分が同一であり続けるなんてことは到底あり得ない。自分は毎日刻々と、自分の知らない間に変わっていくものだし、例えば「自分らしさ」というゴールに近づきたかったとしても、それは追いかければ追いかけるほど遠ざかるような、そんなものだと思うんです。立ち止まることもどこかで終着することもない。この曲で歌っているように、彷徨って自分らしきものを見つけたとしてもすぐに別れは訪れるし、そもそも「ほんとうの私」はどこにもいない。……そして、今自分が持っている言葉や思いで身を繕う。

この曲を作るにあたって、雰囲気作りにはかなりこだわりました。誰かに自分らしさを聞いて初めて分かることもあるかもしれないけれど、結局自分が自分らしいかを決めるしかない。だから、自分探しは真っ暗の宇宙を漂うような、そんな孤独な作業なんだと思います。バックで鳴っているストリングスやシンセ、パッドはそういったものを表現しています。

まあ、折角なのでKCSらしい(?)技術的な話を一つ。今回パッド(イントロやBメロでほわわんと鳴ってる空気みたいな音です。まあ、空気というよりは人の声に近い感じがするかもですが)にはSteinbergのPadshopを使用しています。これはグラニュラーシンセシスを用いた音源で、そのグラニュラーシンセシスというのは、いわば「音を粉々にして再構成することで新しい音色(おんしょく)を作り出す」というものです。正直何言ってるか分からないと思いますが、僕もよく分かりません(おい)。まあ、そういう音なんだと思ってください。そして、そういう音を使用すると何が良いかといいますと、音の抑揚や雰囲気を割と色々いじれるので、今までにないような自分でも驚くような音色に出会える、というところなんですよね。自分でも驚くような、なんて言ってしまうと、「曲作る人は初めから狙って音を作り出すものではないのか」とか言われてしまいそうですが、偶然出来たり発見した音も取り入れる、即ち新たな音との出会いは、作曲の醍醐味の一つです。うーん、やっぱりKCSっぽい感じがしない、この記事。というか、自分の知識が無さ過ぎて結局、技術面に全く踏み込めてませんね(汗)

というわけで、長くなってしまったので本日はこれくらいで。音楽班はこの夏、定期的にSound Cloudで曲を紹介していく予定ですので、そちらもお楽しみに。それでは。

【音】うなりってナンジャラホイ?


うなりが聞こえないよぉ

おはこんばんちは(´・ω・`)

4月始め以来の投稿になります。ん~、そろそろ皆も5月病かな?

今回のテーマはズバリ【うなり】です。
うなりって言うのは

うなりとは,音の高さがわずかに異なる二つの音が鳴っているとき,各々の基音の周波数の差に相当する周期で音の強弱が聞こえる現象です. このとき二つの音は,ひとつの音の強弱が変化しているように聞こえます. 二つの音の高さがある程度まで離れると,両者は一つの音の強弱ではなく別の二音として聞こえます.
-引用”うなり [物理のかぎしっぽ]

だそうです。まぁ、知ってますよねみなさんも。

でね、なんでこんなこと今更言うのかと。

ちょっと話はずれますが

人間ってどうやって聴覚してると思いますか?

完全な私見ですが、頭のなかでフーリエ変換っぽいことがなされて周波数成分に分けられて知覚なんて感じじゃないんですかね?(フーリエ変換わかんない方はこちらがおすすめ1.フーリエ級数(やる夫で学ぶディジタル信号処理)

人間、音の高低なんかは割りと機微に反応しますから周波数らしいものを捉えてるものは確かなのですよ。

でね、人間って位相差には弱いらしいんですわ。

つまりは、聞いた音を周波数に分けてその成分の強さだけに反応してるってことですよ。

うん?

そうここでおかしなことに気づきませんか?

「あれ、これうなり知覚できなくね?」

そうですよね。例えば同じ音量の400Hzの音と440Hzの音を合わせたら、40Hzのうなりが生まれるはずですが、さっきの過程だと、400Hzと440Hzの成分が同じだけ立って終わりですよね。決して40Hzの成分なんて生まれません。

あれ、おかしいなと。そこでお互いが干渉して、成分が時間方向で変化とかしないかとか考えたんですが、当たり前ですがフーリエ変換上そういうことは起こりえません。sin波の和音はただのsin波の和音です。

そこで、ネットで軽く調べたんですが、見つからず、しょうがないので伝家の宝刀『オシエテワカルヒト』を抜いて、信号処理の教授にも聞いてみたんですがあんまり良い回答は得られませんでした。むしろ「わかったら教えて」とまで言われてしまい。もうこうなったら自力で解くぞと頑張りました・・・・・。一時間

わかりました。個人的にはこの問題は終息しました。

では、そのお話を

まずポイントは離散フーリエ変換です。そもそも人間ってそんなに周波数領域に分解能ある訳ないよな~と電車の中で閃きまして、そしたら「おっとこれは窓関数を考えなくてはならんですなぁ」と考えにいたりました。これは一悶着ありそうです。

調べました。今回は以下の様な設定で実験してみました。

$$f_s = 40kHz, f_0 = 400Hz, N=100$$

\begin{aligned}
ただし、f_{s}はサンプリング周波数。\newline f_{0}は基底となる周波数。\newline NはDFTで使うデータ数。
\end{aligned}

この設定のもとで、以下の式について考えました。

\begin{aligned}
F(k) = |\sum_{n=0}^{N-1}  (sin(2\pi f_0(t + delay)) + sin(2\pi (f_0 + beat)(t + delay))\exp( -j\frac{2\pi k}{N} n) )|
\end{aligned}

$$ ただし、t = n/f_s、 beatはうなりの周波数$$

単に、2つのsin波に対してDFTしてるだけです(ただし、今回は振幅のみに注目するので最初から絶対値をとりました)。delayは時間で人間がこの音を聞くタイミングのズレを表しています。今回はこのdelayを動かすことで、その変化を追います。

で、以下が結果です。

まず40Hzのうなりから

400Hzと440Hzの合成波の400Hz成分
400Hzと440Hzの合成波の400Hzの成分

下の時間軸はdelayを動かした様子です。図にも書いてありますが、これは400Hzの周波数の振幅成分を図示したもので、ちゃんと書けば

\begin{aligned}k=1(=\frac{f_s=40kHz}{N=100}\times \frac{1}{400Hz})\end{aligned}

なのでF(k=1)をdelayに関して[0.0s,0.05s]の範囲で動かしたものとなります。

どうでしょう、ちゃんとうごめいてますよね。しかもその周期はどうやら40Hzです。つまり、400Hzの音の成分が変化しちゃってるんですね。

一応、こっちも見ときましょう。下図は400Hzだけを鳴らしたときの400Hzの周波数成分です。

400Hz単音時の400Hzの成分
400Hz単音時の400Hzの成分

当たり前ですね。そりゃそうだという話です。こういうふうに聞こえてるおかげで、一定の音量の音を我々は知覚できます。逆に先のうなってる方は音量が400Hzのが変化してますね。これがうなりの本質です。

なんだか、ゲシュタルト崩壊気味な気分になってくる感じがします。

(僕だけ?)それは、何故か?

それは、うなりが聞こえるのはわかったけど、和音を聞いているんだからもちろん440Hzの成分も検出されないとおかしいという点だと思います。

ですが、すぐにそれが無理であると気づきます。例えば今回なら440Hzの成分はDFTではでてきません。連続周波数空間で440Hzの成分だったものはそこら中に分散しています。では、その様子も観察してみましょう。

下図は先程のうなりの図の次の周波数成分つまり、F(k=2)です。

400Hzと440Hzの合成波の800Hz成分
400Hzと440Hzの合成波の800Hz成分

なんかごちゃごちゃしてます。最初の400Hzの振幅に比べると大分小さい値なのと、なんとなく周期的なことはわかりますし、それはどうやら0.05sの間に45,6周期がありそう。つまりは約900Hzってことも読み取れます。900Hzって大体440Hzの二倍ですから関係がありそうです。

で、よく考えたらこの振幅は元々はF(k=2)の絶対値をとったもの。つまりは周波数は振幅上では2倍されたものが観測されるはず(2倍角の定理)なのでこれでOKということになりますね。ちゃんと800Hzの成分の中に残骸があったわけです。

で、残骸があったのはわかった訳ですが、「それが?」っていうね。やっぱ440Hzは聞こえてないじゃんと。「これは800Hzでしょ、その成分が440Hzで振動してるだけっしょ」、つまりは800Hzの音が440Hzでうなっていると先ほどの文脈から行くと言えるわけです。流石に440Hzがうなってるってのはおかしいし、そもそも800Hzなんて聞こえてないはず・・・。んん、くまった

消えた440HZ

ここからも持論で申し訳ないのですが、視覚で例えてみましょう。

人間は赤、緑、青の三色しか見えてないってのは割りと有名だと思うのですが、じゃぁの中間色はどう見てるかというと、赤と緑が同じくらい反応したらオレンジみたいな感じで折衷案みたいなのを頭が解釈してるようです。三原色の合成

今回の聴覚の例もその一つではないでしょうか?

つまりは「400Hzと800Hzが400Hz強めで800Hz弱めで反応してる=>おっしゃ440Hzや」みたいな論理展開がされてても不思議じゃありません。

ただ、興味深いのは視覚なら「赤色」と「オレンジ色」を混ぜると「赤が強いオレンジ色」という単色にみえるのに対して、音の場合は400Hzと440Hzをしっかりと分別してみていることです。普通、400Hzと440Hzを聞いて「あっ420Hzがなってる」みたいには感じませんよね。視覚と聴覚では混ざると言っても聴覚のほうがより分けたい気持ちが強いみたいです。

このことからわかるのは、今回の例ではN=100、fs=40kHzとテキトーに決めましたから、DFTでは400Hzと800Hzと言った周波数しか持ちえませんでしたが、人間でそうである保証はどこにもないですね。

例えば、N=2000として、DFT上で20Hzごとに成分を持てるようにしてやれば、無事440Hzの成分も持つことができます。ただし、この場合人間の耳にはうなりは聞こえないはずです。それは、先ほどの例の様に400Hzの成分に440Hzの成分が分散して来ないからです。

fs=40kHz,N=2000の時の400Hzの成分 が一定になっている様子
fs=40kHz,N=2000の時の400Hzの成分

fs=40kHz,N=2000の時の400Hzの成分 が一定になっている様子
fs=40kHz,N=2000の時の440Hzの成分

 

実際、周波数の異なる2つの正弦波の合成波を聞いてみるとわかるのですが、その周波数差を徐々に大きくしていくと、最初は確かに唸ってるのが知覚できるのですが、途中から「あれ、これ唸ってる?まぁ唸ってるっちゃ唸ってる?けど、いきなり聞いたら只の和音かなぁ?ハーモニー的な?」ってなります。これは、人間の分解できる周波数成分に相方の正弦波が入るかどうかってのがボーダーになっていること、そして、人間の分解できる周波数成分に入っている度合いが連続的に推移しそうなのは数式からもなんとなくは推測されます。

要はうなりと言っても「うなり or そうじゃない」と二値化できるものではなくて、連続的に変化しているのがわかります。

このことの応用として、例えば何百人とか何千人規模の人を集めてうなり度合い見たいなのを今回で言えば400Hzとそれ以上の周波数の波の合成波に対して答えさせることで、統計的にどこからどこまでが人間の分解できる周波数なのかがわかるんではないかと思います。例えば、430Hzあたりでたくさんの人が和音だけになったと答えれば、30Hzが400Hz付近での人間の周波数分解能といえるのではないでしょうか?

まぁ、人間はDFTほど単純な機構をしているともあんまり思えませんが、数多くある指標の一つくらいにはなるかと、つか、もうありそう。

実際に聞いてみよう

最後に、うなりがうなりでなくなる様子を確かめるために音源をおいておきます。暇だったら聞いてみてちょ

以下音源についての説明

400HZと400Hzから500Hzまでの和音 どこまでがうなって聞こえるかが、確かめられます。 和音は最初の1秒がそれぞれ独立に0.5秒ずつなって、そのあと2秒それらの和音がなります。
片方は400Hzで固定ですが、もう一方は400Hzから10Hzずつ大きくなっていきます。