hobby.この広告は、90日以上更新していないブログに表示しています。2016-12-19リアルタイムFM合成を考える。Tips最近になってようやくFM合成をどのように作ればいいのかが分かったので、リアルタイムで合成する時はどのように実装するのかを考える。目標はMAX/MSP上での実装。実装する前にFM音源について学びましょう。まあ大体wikiを見たら分かるのですが、重要なところを抜き出したものが以下の通り。DX」などで検索して確認してみましょう。氏家さんのプレイに魅了されることでしょう。実際にDXなどで動いている数式は以下のとおりです。数式にあるとおり基本形はsin波をsin波で変調しています。これをもっとsin波に限らず一般的な波形に当てはめるとこのような感じに。t:時刻この数式が示しているのは、ある時刻tのモジュレータ波形の値だけずらした時刻t+Fm(t)のキャリア周波数を出力として出す、ということがわかります。簡単にPythonで組んでみて、波形を確認しましょう。right')plt.show()こういった感じで変調指数やモジュレータ周波数などを変えることで複雑な波形の合成が可能となります。それと同時に波形の変化の予想が難しく音作りが困難になるといったデメリットも生じています。これがFM音源の奥深さというやつですね。前置きはここまでにして重要なのはこれをリアルタイムで合成するという点です。indexには任意の値(float)が与えられます。なると今まではsin波の計算だけで済んでいたものがそうともいかなくなりました。すればいいでしょう?そこで先ほど、FM合成はある時刻tのモジュレータ波形の値だけずらした時刻t+Fm(t)のキャリア周波数を出力として出す、ということが分かりました。モジュレータから受け取った値を無理やり時間軸に直して、キャリアにおけるその時刻の振幅を得ればいいわけです。実際に検算してみましょう。サンプリング周波数を44100[Hz]し、t1=5/44100と置きます。sin(t1))=0.000226762509435となります。モジュレータから受け取ったsin(t1)を時間軸に直したいのですが、波形は配列でインデックスでしか参照できません。サンプリング周期で除算することでインデックスに変換します。4.99999998929ここでインデックスが小数点になるので線形補完をつかっておおよその値を求めます。decimal=0.99999998929と置きます。sin(t1))の値を近似します。sin(t1))=0.000226762509435よってうまく近似できていることが分かりました。実際にpythonで計算したところ誤差は-2.71050543121e-20だそうです。サンプリング周波数を下げたり高周波成分になる程精度は下がりますが、そこは仕方ないので割り切り。実際にこの方法で波形を近似していきます。right')plt.show()なかなかうまく近似できました。当然ですが、モジュレーション関数を書き換えても同様の結果が得られます。お気付きの方もいると思いますが、この状態ではまだ大きな欠陥が存在します。モジュレーション関数であるsin(x)が取る最大値は1です。このときFm(t)=44100になります。振幅値を上げたらその分だけFm(t)が増加します。基本的にリアルタイムで処理する際、未来の波形は取得できません。取れてもサンプリングフレーム分だけです。そのため、リアルタイムで処理するためにはあらかじめ大量のバッファを確保して、基本的に過去の波形を参照し続けるという方式でないと理論上不可能です。大量のバッファには適当な波形を起動時に生成しているかゼロ・パディングでバッファをクリアしているのでしょう。そこらへんは、実際に実装するときに考えましょう。20:44リアルタイムFM合成を考える。Tumblr広告を非表示にするもっと読むコメントを書く2016-06-23AudioUnitでFuzzFaceを作る。Hendrixも使っていたりする超有名なエフェクターですね。これが欲しいのですが、お金がないです。自作するにも環境がないです。あとパーツを買う元気もないです。そこでAudioUnitでこれを実装しようという話です。プログラム上で組めればタダですから。ニッチな内容なので誰も興味ないでしょうが、自分用のメモとしてここに残しておきます。16:45AudioUnitでFuzzFaceを作る。Hzの変換式Tips最近、論文を読んでたら結構な割合で周波数軸をcent表記している人が多い。考えたらチューナーなどでも合わせる対象の周波数に対してどれだけずれているかをcent表記で示していることが多い。(代表例:GarageBandのチューナーの単位もcent)"ではcentとはなんだ?"といますと、wikipediaでは以下のように書かれています。セントは2つの周波数の比である。平均律の半音の間隔は100セントと定義される。オクターヴ(2つの音の周波数比が2:1)は12半音であり、1200セントである。https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%B3%E3%83%88_%28%E9%9F%B3%E6%A5%BD%29なんとなく分かるけど実際にHzからcentに変換するにはどう計算するのか分からなかったので、今回それについて考えてみます。パラメータの単位設定AudioUnitsAudioUnitsを何個か作ったなかで情報が少なくて面倒臭くなることが幾つかあったので、とりあえず記事にまとめてみます。これぐらいはすぐに調べたら分かるような内容ですが一箇所にあるほうがよさそうなので。#その2AudioUnits前回は主にFilterKernel(AUKernelBase)を中心に、"どのように音響処理を書き込んでいくのか"を読み解いていきました。処理の内容だけ書いても、"それをどのように制御するのか"、"GUIにどのような情報を提供するのか"などのAudioUnitsにおける外面に関する部分をどんどん読み解いて来ましょう。今回のAudioUnitEffectExampleのFilter(AUEffectBase)クラスやら定数などの宣言に着目していこうという回です。対象は、以前の記事で落としたであろうAudioUnitのサンプルコード群の中にAudioUnitEffectExample。本来の目的はエフェクタな訳で、他のAudioUnitGeneratorExample(PinkNoise生成)やAudioUnitInstrumentExample(おそらくMIDI制御のsin波シンセ)には目もくれず、これを弄ろう。最初、StarterAudioUnitExample(Tremolo)を弄ろうと思ったんだけど、何かぱっとみ書き方がややこしい(読むのが面倒くせえ)ので、見た感じがすっきりしているFilterDemoさんを見ていこうという感じ。あとCocoaGUIが用意されているので要らない場合はCocoaGUI関係のソースコードを消せば、StarterAudioUnitExample(Tremolo)のような初期のパラメータ設定ウィンドウが表示されるので、今回はそうします。そのため、実はFilter.hをゴミ箱にポイーしても大丈夫です。ただでさえ中身が少ないのによく見たら全部CocoaGUIに関するものだったので。ここから内部処理に触れていきますが、著者はC++を触ったことある程度の人間ですので何か間違いや勘違いなどがあると思われますが、その時はコメントか何かで報告を......。Tumblr広告を非表示にするもっと読むコメントを書く2015-04-13PyAudio環境構築Python将来的に音響解析などに手を出したいと思ったのは良かったのだが、それを行う言語をどうしようと悩みあげた挙句、pythonさんを利用することにした。理由はmatlabとかお金かかるし、最近はpythonさんが人気あるとか、そんな感じ。決めたのは良かったのだけど、PyAudioの環境構築に中々手間取ったので備忘録。2.2.0の中に既にpyaudioがあるもよう。そのため色々と中身を変更しました。(2)NewPostsリアルタイムFM合成を考える。AudioUnitでFuzzFaceを作る。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。