投稿

ラベル(Sound)が付いた投稿を表示しています

歴史的な音声合成ソフト「XKL」で遊ぶ(4) ~仕組み編~

イメージ
XKLで遊ぶ記事 の第4弾。 前々回・前回で XKL の基本操作を追っていきました。これでいろいろな音声が生成できそうです。 もっと音声合成で遊ぶために、各パラメータの意味を把握しておきたいところです。そのまえに、Klatt Synthesizerの歴史と構造についてざっと調べてみました。 おおまかな歴史 1. 初期の Klatt Synthesizer (1980年) Dennis Klatt氏が最初に Klatt Synthesizer を発表したのは、1980年の " Software for a cascade/parallel formant synthesizer " という論文のようです。 https://www.fon.hum.uva.nl/david/ma_ssp/doc/Klatt-1980-JAS000971.pdf この1980年版の Klatt Synthesizer は以下のような構成です。 [Klatt, 1980] より引用 これが最もベーシックな Klatt Synthesizer です(細かい部分は以降で見ていきます)。その後のバージョンで細かな変更や拡張が行われるものの、大まかにはこの時点ですでに完成されています。 この1980年の論文のなかで、「HANDSY.FOR」というFORTRAN のプログラムが掲載されています。このプログラムは当時のコンピュータである DEC PDP-11 向けに書かれたものでした。以下のリポジトリでは、gcc の GNU Fortran でコンパイルできるように整備されています。 https://github.com/jh4xsy/klatt80 すこし脱線しますが、初期のKlatt Synthesizerをベースに作られたのが DECtalk です。 車椅子の理論物理学者であるスティーヴン・ホーキング博士の機械音声は DECtalk で合成されたものです。 また、テクノミュージックの巨匠である Kraftwerk が「Music Non Stop」で使った合成音声も DECtalk だそう。 ちなみに DECtalk は、現在はオープンソースで公開されています。各プラットフォーム向けのバイナリも配布されているので手軽に試せます。 https://github.com/dect...

歴史的な音声合成ソフト「XKL」で遊ぶ(3) ~時変パラメータ編~

イメージ
XKLで遊ぶ記事 の第3弾。時間に応じて合成パラメータを変化させてみます。 d: パラメータを時間変化させる コマンドメニューの「d  CHANGE synthesis parameter time function」をダブルクリックすると、パラメータを時間変化させる画面になります。 ここでは パラメータ F0 (基本周波数, 声の高さに相当する) を時間変化させてみます。 グラフが開きます。続いて時刻を入力します。ここでは 100 ms の位置の値を設定することにします。 続いて、パラメータの値を入力します。ここでは 100 ms 地点を 100.0 Hz にしたいので 1000 を入力します。 このあとは、時刻と値を交互に入力していきます。たとえばこんな感じ。 入力したパラメータ設定はグラフにも反映されていきます。入力した値が直線で結ばれていくイメージです。 音声合成するとこんな感じ。声の高さを時間変化させることができました。 これと同様に、他のパラメータ(フォルマントなど)も時間変化させることができます。 v: 時間変化させたパラメータを見る 現在の時間変化パラメータを確認するには「v  PRINT (screen) varied parameters」を選びます。 チャレンジ: 音声 /ba/ を合成する 以上で時間変化のための操作説明はおしまいです。せっかくなので、このやりかたでひとつ音声を作ってみます。今回は、有声子音と母音からなる 「ば」(/ba/) の音声 を作ります。 /ba/ の具体的なパラメータ設定は、上智大学・荒井研究室のサイトのページを参考にしました。 F2開始周波数と調音位置 その2 (F2-onset frequency and place of articulation Part 2) このページの元になった論文は以下から閲覧できます。 K. Tomaru and T. Arai: "Role of labeling mediation in speech perception: Evidence from a voiced stop continuum perceived in different surrounding sound contexts" (2016) 論文では、以下のようにパラメータを変化させるこ...

歴史的な音声合成ソフト「XKL」で遊ぶ(2) ~基本操作編~

イメージ
XKLで遊ぶ記事 の第2弾、基本操作編です。 XKLで 母音「あ」を合成してみる 使い方を紹介しつつ、母音「あ」を合成するところからはじめてみます。 XKLは、使いやすさに全振りした現代のソフトウェアと比べると、ちょっと手ごわい感じがします。私自身も最初は意味不明に感じて投げ出しそうになったのですが、試行錯誤しているうちに使い方がわかってきました。 さてこのソフト、XKLでできることは大きく2つに分かれます。 音声合成 例:パラメータ(フォルマント情報等)を入力することで、音声波形を合成する。 音声分析 例:録音した音声ファイルから、フォルマント周波数を調べる。 音声合成だけでなく音声分析もできてしまう高機能さゆえに、少しわかりにくくなっている気がします。XKLを起動してなんとなく使おうとすると、分析機能ばかりが目に入ってきて、「一体どこを操作すれば音声合成できるの…?」と迷子になってしまいがちです。これらを意識的に区別するとわかりやすいと思います。 音声分析モードで起動する 我々がやりたいことは音声合成なのですが、起動直後は音声分析に特化したモードになっています。 XKLは起動時になんらかの音声ファイルを指定する必要がありますが、とりあえずは同梱されている「test.wav」を開くのがよいと思います。 ./xkl-3.2  ./test.wav これで音声ファイルが開きます。ちなみにこの test.wav は Klatt Synthesizer で合成された音声です。 いろいろな操作ができますが、必要最低限の機能をご紹介します。 「左クリック」または「Alt+左クリック」で時刻カーソルが動かせます。 「中ボタンクリック」または「pキー」で音声が再生できます。 ちなみに私の環境だと再生終了後に謎のグリッチ音が入るのですが、実用上は問題にならないので無視しています。 この時点では、まだ音声分析しかできない状態です。ここから音声合成に入っていきます。 音声合成モードに入る 音声合成ができる状態にするには、メニューから「 Synthesize 」を実行します(または「Shift+Y」キーを押す)。 そうするとダイアログが出てきます。 これがすこしぶっきらぼうな書き方で分かりにくい……。 聞かれていることは要するに、 「音声合成モードのデータを用意するにあたって、デ...

歴史的な音声合成ソフト「XKL」で遊ぶ(1) ~導入編~

イメージ
1980年代から続く音声合成ソフト XKL を使ってみよう!という記事の第1弾、導入編です。 (記事は  XKLカテゴリ  にまとめてあります) はじめに ここ数年で、VoiceVox や Synthesizer V に代表される高品質なAI音声合成ソフトが広く使われるようになりました。もはや肉声と区別できない領域に達しているソフトもありますが、ボカロの世界でよく言われるように「リアルさだけがすべてではない」ということを常々思っています。 機械音声を創作するうえで、そもそも声として聞こえるとはどういうことなのかという基本に立ち返ったうえで、人間の職人技によって調声できる「筆」のような道具が欲しいと思いました。機械学習による音声合成とは真逆の方向性です。そこで、昔ながらの合成方式である フォルマント合成 と呼ばれる技術を考えてみます。 フォルマント音声合成の歴史を調べると、 「Klatt Synthesizer」 や 「KLSYN」 と呼ばれる音声合成システムが登場します。 この「Klatt Synthesizer」というのは、 Dennis H. Klatt  氏 (米MIT) が1980年代に発表した音声合成システムで、いわばレジェンド的なソフトウェアです。古典的な音声研究において有名ですし、DECtalkのベースにもなりました。ついでにいうと、本ブログで10年以上前に書いた記事「 C言語で音声合成もどき 」も、この Klatt Synthesizer が元ネタだったりします。 さてこの Klatt Synthesizer ですが、私はいままで論文でしか見たことがありませんでした。しかし調べてみると、本家Klatt Synthesizerが 2025年現在でも使える ようなのです。 サイト:  The xkl project 正確にいうと様々存在するバリエーションのひとつのようですが、Klatt氏が実装した KLSYN88 を拡張するかたちで作られていることから、私が知るなかでは最もオリジナルに近いものだと思っています。 このソフトにいろいろと数値を打ち込んでやることで、本物のKlatt Synthesizerによる音声合成が再現できてしまう。これはなかなか面白そうです。 というわけで今回はXKLを使った音声合成で遊んでみます...

ホワイトノイズを生成する

イメージ
最近まで、ホワイトノイズを作るには、一様乱数を使えばよいと思っていた。 たしかに一様乱数でも、ちゃんと周波数特性が均一なホワイトノイズになる。シンセやAudacity等でホワイトノイズを生成すると、たいてい一様乱数が出てくる。 しかし、信号処理の世界では 正規乱数 (値が正規分布的に分布する乱数)を使うほうが一般的らしい。 正規乱数によるホワイトノイズのことを「ホワイトガウシアンノイズ」と呼ぶこともある。 なぜ一般的な信号処理で「正規乱数によるノイズ信号」(ガウシアンノイズ)を使いがちなのかというと、正規乱数は「最も平均的なノイズ信号」といえるからだ。 あらゆる雑音信号をたくさん集めて平均していくと、集めれば集めるほど正規乱数に近づいていく(これは 中心極限定理 から言える)。 また、ガウシアンノイズは数学的に扱いやすい性質がいろいろとあり(ここでは詳細は省く)、数式上の利便性もある。 調べたところ、正規乱数のメジャーな生成方法には、おおよそ3種類があるらしい。 1. 一様乱数を12回足して6を引く(近似) 中心極限定理をそのまま利用した方法。 一様乱数を たくさん足し合わせて平均 すれば、正規乱数に近いものが得られる。 近似なので精度は高くないが、ちょっとした用途ならこれで十分かもしれない。 また、乱数を1つ作るのにループを要するため、大量に生成する場合には遅いという話も聞く。 亜種として「16回足して8を引く」実装もある(例: Web上で音声合成ができる  PinkTrombone )。 要するに $2N$ 回足して $N$ を引けばよい。 2. ボックス・ミュラー法 2つの一様乱数 $ 0 < a, b < 1 $ をもとに、2つの正規乱数 $ x, y $ を生成する方法。 $ x = \sqrt{-2 \log a} \cos 2 \pi b $ $ y = \sqrt{-2 \log a} \sin 2 \pi b $ おそらく最も教科書的でよく知られている方法で、実装も簡単。 三角関数・対数・平方根といった数学関数を使うことになるので、オーディオ信号生成のように大量の乱数が必要な用途ではもっと高速化したくなるケースがあるかもしれない。 3. ジッグラト・アルゴリズム 超ざっくりいうと、ルックアップテーブルを使う...

MATLAB版WORLD を GNU Octave で使う

イメージ
音声分析合成システム  WORLD  を GNU Octave 上で動かしてみる。 WORLDにはC++版とMATLAB版がある。ふと思い立って試作するには、C++ よりも MATLAB のほうがはるかにラクだ。しかし MATLAB は高価なので、個人で手を出すのは難しい。そこで MATLAB 互換のオープンソースソフトウェア Octave を使うことにした。 この記事では MATLAB版WORLD を Octave で動かすときの注意点と、WORLD で声をこねくりまわして遊ぶためのメモを書き連ねていく。 注 : この記事のとおりにOctaveで動作させると、 C++版や本物のMATLABで実行したときと結果が一致しない (原因はおそらくビルトイン関数の結果が微妙に異なるため)。一応それらしい結果になるし、単に「動いたら面白いな」という程度なので、ここでは問題ないと考えて割り切っている。正しい結果が必要なときは Julia  の  WORLD.jl パッケージ  を利用したほうがよいとおもう。 WORLD の使い方は、おもに森勢先生の公演スライドとPDF資料をベースにしている(URLを記事の最後に載せてある)。とてもわかりやすい資料なので、目を通しておくべし。 環境 Windows 10 (x64) GNU Octave  4.2.1 WORLD  v0.2.1_4 (Matlab) WORLD を使う準備 Matlab版WORLD  のZIPファイルをダウンロードして解凍しておく。 基本的に Octave は MATLAB 互換なので、普通はこのまま動作できる。 ところが、Octave には実装されていないMATLABの関数が存在する。 今回使った WORLD v0.2.1_4 (Matlab) で使われている rng関数 と interp1q関数 は、現時点では Octave に実装されていない。 というわけで、埋めあわせ用の関数を用意した。 rng.m function rng(x) randn('seed', x) rand('seed', x) end interp1q.m function...

PortAudio を VS2010 Express でビルドする

PortAudio を Visual C++ から利用しようと思ったのだが、導入に手こずってはまりかけた。 環境: Windows 8.1 (x64), Visual Studio 2010 Express, CMake 3.2.2 使ったソースは pa_stable_v19_20140130.tgz。 このなかにある build/msvc 以下のファイルは、VS2010で開くとプロジェクト変換に失敗してしまう。 検索してみると VS2008 ならうまくプロジェクト変換できるという情報( PortAudioでリアルタイム入出力制御 (1) )もあったが、今回のPortAudioのためだけに環境を構築しなおすのはあまりにも面倒くさすぎるので試さなかった。 最終的には、CMake を使ってVisualStudioプロジェクトを生成したところ、うまくビルドできた。 詳しいことはPortAudioのCMakeに関するドキュメント( Creating MSVC Build Files via CMake )に書いてある。 以下にざっくりと手順を書いておく。 CMake 2.8以降をインストール する。 PortAudio から ASIO を利用したい場合は ASIOSDK をダウンロード 。フォルダ名を「ASIOSDK2.3」から「ASIOSDK」にして src/hostapi/asio にコピーする。 CMake GUI を起動 。「Where is the source code」には CMakeLists.txt があるディレクトリ、「Where to build the binaries」にはVS2010プロジェクトを作るディレクトリを指定する。 「Configure」をクリック 。ドロップボックスからVisualC++のバージョンを選ぶ。 必要に応じて PA_USE_ASIO などのオプションをいじる(オプションを変更する場合、再度Configureする必要がある)。 「Generate」をクリック 。指定ディレクトリにVC++プロジェクトが生成される。 いままでほとんどCMakeを使ってこなかったけれど、思った以上に便利で感動した。

基本波形の生成

イメージ
オーディオやマルチメディア関連のプログラムを書いていると、手早くノコギリ波や矩形波を生成したいことがある。 そこで、簡単にいろいろな波形を生成する方法をまとめる。 1. ノコギリ波 1サンプルごとに少しずつ値を足していくと、直線的に増加していく波形ができる。 値が 1.0 を超えた瞬間に 0.0 へ戻すことで、ノコギリ状の周期波形が生成できる。 これは、値の小数点以下のみを取り出すことで実装できる。 実装してみる。 以下のコードでは、オーディオ信号として扱いやすいよう出力値の範囲を 0〜1 から -1〜1 へ変換している。 double sawtooth(double 周波数, double サンプルレート) { static double phase = 0.0; // 初期値 phase += 周波数 / サンプルレート; phase -= floor(phase); // 整数部分を引き算 return 2.0 * (phase - 0.5); // -1.0~1.0 の範囲に広げる } 「小数点以下を取り出す」を「1.0で割ったときの剰余」として実装する方法もある。 double another_sawtooth(double 周波数, double サンプルレート) { static double phase = 0.0; // 初期値 phase += 周波数 / サンプルレート; phase = fmod(phase, 1.0); // 小数部分を取り出す return 2.0 * (phase - 0.5); // -1.0~1.0 の範囲に広げる } プログラミング言語によっては(C# など)、浮動小数点数(float や double)に対して剰余演算子 % が使えるので、この実装方法のほうがシンプルに書ける。 2. 矩形波 ノコギリ波が 0.5 を超えたら 1.0、超えなければ -1.0 を出力する。 条件を「0.75 を超えたら 1.0 を出力」に変えれば、デューティ比25%の矩形波になる。 double pulse(double 周波数, double サンプルレート) { static double phase =...