最初の記事 7月 08, 2012 このたびブログをJUGEMからBloggerへ移転しました。 今のところJUGEMのほうを消す予定はありませんが、完全に放置状態となります。 前ブログ(http://moge32.jugem.jp/)と同様、プログラミングの話題が中心となると思います。 更新頻度は少ないとは思いますが、引き続きよろしくお願いします。 コメント
基本波形の生成 11月 02, 2013 オーディオやマルチメディア関連のプログラムを書いていると、手早くノコギリ波や矩形波を生成したいことがある。 そこで、簡単にいろいろな波形を生成する方法をまとめる。 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 =... 続きを読む
(1)C言語で音声合成もどき ~WAVファイルを生成する~ 8月 11, 2012 この記事は素人が音声合成で遊んでいるだけの記事です。完全に行き当たりばったりなので、紹介している内容の保証はできません。 また、記事の内容を予告なく変更することがあります。 「C言語で音声合成もどき」ということで、このシリーズではフォルマント合成と呼ばれる手法を使った音声合成プログラムをC言語で作っていきます。 本題の音声合成に入る前に、まずは肩慣らしとして 音声ファイルを作るプログラム をつくります。 今回は 8bit, 44100Hz, 1ch の WAV形式 のファイルを作成するプログラムを書いてみます。 ( この記事では、比較的実装が簡単なWAV形式を扱います。 ひょっとするとMP3形式等のほうが馴染み深いかもしれませんが、MP3ではデータ圧縮にやや複雑なアルゴリズムを使うことになります。) なお、WAVファイルの構造については WAVファイルフォーマット WAVE file format を参考にしました。 続きを読む
(2)C言語で音声合成もどき ~母音の生成~ 8月 15, 2012 この記事は素人が音声合成で遊んでいるだけの記事です。完全に行き当たりばったりなので、紹介している内容の保証はできません。また、記事の内容を予告なく変更することがあります。 生成した「お」の波形 今回は本題の音声合成に移っていきます。 前回 は波形データをWAVファイルに書き出す部分を作ったので、ここからはさっそく母音の合成をしていきます。 ざっくりいうと人間の声は、 声帯 で基となる音がつくられ、 声道 で加工されたものです。 今回のプログラムは、この「声帯→声道」という構成を参考にして音声を合成していきます。 まずは、声帯にあたる部分から実装することにします。 声帯が振動すると、周期的な波が発生します。 つまり、なんらかの周期的な波を使えば模倣できそうです。 一般的なシンセサイザーのようにノコギリ波や三角波を使うこともできますが、ここでは声帯振動の波を模倣した Rosenberg波 とよばれる波形を使います。 以下がRosenberg波の式です。 出典: https://dspace.jaist.ac.jp/.../896paper.pdf のP14 (2.1)、一部式の変形・表記変更あり τ1は 声門開大期 *1 の長さ 、τ2は 声門閉小期 *2 の長さ を表します。 *1 声門開大期……声門が閉じた状態から開ききるまでの時間 *2 声門閉小期…… 声門が開いた状態から閉じきるまでの時間 これらの値は、τ1 + τ2 が 0〜1 の範囲におさまるように決めます。 今回は τ1 = 0.90, τ2 = 0.05 としました。 Cで書くとこんな感じです。 double GenRosenberg(double freq) { /* Rosenberg波を生成 */ static double t = 0; double tau = 0.90; /* 声門開大期 */ double tau2 = 0.05; /* 声門閉小期 */ double sample = 0.0; t += freq / (double)サンプリング周波数; t -= floor(t); if (t <= tau) { ... 続きを読む
コメント
コメントを投稿