ラベル FM音源 の投稿を表示しています。 すべての投稿を表示
ラベル FM音源 の投稿を表示しています。 すべての投稿を表示

2020年6月12日金曜日

FM trial v4.3リリース!!



会社で使う動画を作る為に、
超久しぶりにFMtrialをCUBASEに刺して、
ドラスピのジャングルを弾いて、それを撮影していた。

そしたらその夜、
1年ぶりくらいにFMtrialのバグレポが上がる!!

なにこれ!
この偶然すごない!?

しかも、ドラスピを手で弾いてたら、
モジュレータにベロシティが影響するのが
どうもイイ感じじゃなくて、
最終的にはベロシティを全部127にエディットして
本来の音色にしてた所。

ベロシティで音色に変化が付くのが
他には無いウリかなーと思ってたけど、
手で弾くとなんとなく音色がショボいのよね。
実際に弾いてみて初めてわかるって事ある。

その辺をさしゅさんにバシっと指摘されて度肝抜かれた!!

なにこれ!!
すごい偶然!!
運命的なので何か繋がってる!?

後はピッチがチョイと低いというご指摘。
調べたら本当にちょっと低い!!
笑っちゃった。

これは原因わからず、オフセットをかまして修正。
昔Aを440hzで調律した記憶もあったけど実際違ってるし。

とりあえずv4.3リリースです。

あそうだ、mucalc同梱のFMtrialも変更しないと!

2019年7月5日金曜日

FMtrialv4.2リリース!!

遂にFMtrialも使ってくれる人が現れた!!
これは以前mucalcがナノ的にバズったからだと思われます。

発音時に位相をゼロからスタートさせるスイッチと、ピッチベンド幅を調整できるノブを
新設しました。後はパッチファイルをMyDocumentにセーブするように。以前はdllのある
場所にセーブしてたのだけど、windowsのセキュリティが厳しくなってProgramFiles内は
プログラムからイジれなくなったから。まあこれはしょうがない。

そして、リリースから2年、何の音沙汰も無かったFMtrial、
誰かが使うと思ってなかったので作りっぱなしというか自分用にしか作ってなかったので、
早速webに機能解説を入れてみました。
とりあえずこれを見たらなんとなーくわかるのかしら!?

おススメはmucalcでMDXをループでプレイしながら、FMtrialのパラメータを
ぐいぐいといじるのが楽しいです。
往年の名曲をどんどんぶっ壊して別の曲にしてみよう!

こういうのはコンテンツとして成り立つのかなぁ・・。

2017年6月27日火曜日

FMtrialv4.1リリース!!

遂にCUBASE9が32bitプラグインに対応しなくなったのでした。
そこでウチのVSTインストも64bit化が必要なのです。

早速ググって64bitビルドを試みる。

わわわ、結構ビルドエラー出る!!
一つ一つチェックしてみたら、案外シンプルなエラーだったので、
スススと直していくも、png関連のエラーがどうやっても取れない。

「外部シンボルが未解決に~」系のヤツ。

こんなの後で考えたら.libにパスが通ってないってすぐにわかるもんだけど、
その時は64bitのビルドが初めてだったので、これは64bit独特のエラーだ!
なんて思い込み。ソースコードをぐいぐい見続けて、ちんぷんかんぷん地獄へ・・。

ツイッターにその事をふと呟いたら、突然ひらめく。
いや、パス通ってないだけちゃうの、と。

libpngなどを64bitでビルドした後、そこにパスを通したらあっけなくビルド完了。
会社のCUBASE6.5で動作も確認。

いやー、何という事でしょう。
問題ってシンプルな時もあるよね~。
ツイッターで呟いて良かったわ~。

というわけで、FMtrialも遂に64bit化!
誰か使ってくれる人が現れる日は来るのか!!

2017年2月3日金曜日

FMtrial version3.0リリース!!!

いよいよ一区切り、FMtrial version3.0遂にリリースでございます。

遂に4オペレータに対応し、8アルゴリズムガッツリと入ってます。
フィードバックもするし、かなりYM2151に似た音が出ますよ。
ゼヒ使ってみて下さいね。

というわけで、苦労話をここに書きましょう。

まず、エンベロープジェネレータ(EG)が本当に大変だった!!
何となく思いつきで作ったEGも、パラメータによってどんな動きをするかは
シンセの設計者次第という事で、YM2151のイミュを使って

・アタックレート
・ディケイレート
・リリースレート
・サスティンレベル
・サスティンレート

この当たりをパラメータを一つづつ変えてサンプリングして計測、みたいのを
やりましたよ・・。大変だったわ・・。

計測した値を元に計算式を作って、実際にシンセに入れ込んで出力してまた
計測。計測に次ぐ計測。

やっとできたと思って曲を鳴らすとなんか違う。

特にクイーンマリー号の後半部分。

ここはアタックのゆるい音がフワフワと鳴るんだけど、そこが全然違う。

そうだった!!キースケールを全く計算してなかった!!

ということで、キースケールも全部の値で計測。
これが驚愕の造りになってて。
値がリニアでないのよね。なのでノート分全部計測してテーブルを用意。

もう無茶苦茶なやり方だけど、これしかなかった。

だから、実際のYM2151がどう鳴ってるのか全然わかんないけど、
似た感じの音が出るという感じになりました。まあ当初のコンセプト通り
これでいいのでしょう。苦労はソースコードに入ってますのでゼヒ。

そして実際のパラメータを流し込むとそれっぽい音が出るようになったので、
プリセットが必要。

もう何年も前から勉強の為に訪れているVAL-SOUNDの阿保剛さんにメール
でプリセット音としてサイトに乗せている音色データを使わせて欲しいと
連絡した所、すぐにお返事を頂けた!!

超感激!!!

ゼヒ使って下さいとの事!!

めっちゃ嬉しかった!!!

サンプル曲の感想まで頂けて!!大興奮!!!

阿保さん本当にありがとうございました!!

というわけで、プリセットはめちゃ高品質な音が入っています。
音色によってはYM2151にめっちゃ似てたり、またはそうでなかったり。

誰か一人でも使ってくれるといいなぁ~。

2017年1月27日金曜日

FMtrial version2.0リリース!!

遂にオペレータが2つになりました!!
二つになったらそらもうFM変調するしかないでしょうという事で。

早速サンプルを鳴らしてみたので聞いてみてね。

MDXをそのまま鳴らす為に、今回オペレータ3と4を1と2に各パラメータを流し込んで
鳴らしてみました。よってフィードバックは無し。

ドラスピを聴いてわかると思うけど、かなりギョイ~ンといっております。

今回の一番の山場は「テーブル化」!!

毎22マイクロセカンドで計算しないといけないので、イチイチsin()とかlog10()とかexp()
とかでやってるとまあ遅い遅い!!

v1のサイン波でそのまま作ったら、演奏がヨレヨレになるくらい遅い。
2017年になっても、プログラムの高速化は必要なのでした。

そうなると古典的な方法、テーブル化。

計算を事前にしておいて、値を参照するだけなのですな。

今回、ほとんどリアルタイム部分はテーブル化してみました。

自前で全部用意しようと思ったけど、どうしてもピッチ関連だけはx68sound.dllのやり方
を使わせて頂く事になりました・・。むっちゃ大変なのよ、ピッチ関連・・。

実際どこまで作れたかというと、サインテーブルを用意して音程を変えるという所まで
作れたのでございます。ところが、ノートオン後、ノートオフの前にピッチをビビビと
変化させるとものすごいブリブリとノイズっぽいものが乗るのね。

波形を見てびっくり!

ピッチが変わる度に、サインテーブルに送る角度がリセットされるので、波形もリセット
されてしまう感じ。サンプル聴いてみて下さい。(※音量でかいかも)

ざらざらした音を再生する

サインテーブルに送る角度を毎回ゼロから計算するのではなく、角速度というもので
順送りにしていく必要があり、そこが何度やってもうまくいかず、最終的にはギブアップ。
FM変調も結局使わせてもらう事になりました・・。

でも完全に諦めたわけでは無い!全体がまとまってきたらまたチャレンジするつもり。

そのあたりの格闘具合はソースコードを見てみて下さい。

その他、大変だったのはエンベロープのテーブル化。

YM2151の挙動をサンプリングして計算で真似てみました。
結構いい感じにまとまってきたのではないでしょうか。
全く同じではなく、似てる感じが頑張ってる感出てます。

音量をテーブル化すると、音量が変わる時にこれまたノイズが乗るので、ロマンシアは
かなりボソボソいっております。これは2点取って補完する処理を入れなければいけない
けどこれも積み残し。

次はついに4オペレータ化!オシレータの波形追加!フィードバック!あとはパッチ!!
パッチはまた地獄になりそうやな・・。

2017年1月8日日曜日

FMtrialリリース

というわけで、2017年も始まったのでVSTインストをリリース。

FMtrialというVSTインスト、これは自分でFM音源を作ってみたい!というロマンと、
制作過程を小出しにするやり方、VSTインスト制作の日本語記事を増やしたい!
など色々な思いのつまったもの。

実験的で、やってみないとわからないというプロジェクト。

まさに、trialという言葉に込められた意味はそこにある。

今まではvstホストとvstインストを同時に開発もしてきたんだけど、なかなか世の中
に出せないなこれ、という作りで、きれいに整えて出せるまでまだ何年もかかりそう。

だったら、今まで培った技術で同時にコンテンツとして「もつ」ものがあればいいんじゃ
ないかしらという狙いもある。

そして、2151を割とそこそこ再現できている「FMplus」は、再現性や計算量軽減の為
にビッチリとテーブルで組まれていて(先人の知恵を頂いて再現)、もし、テーブルで
はなく計算でFM音源作ったらどんな音が鳴るのかしら、というロマンも。

作りようによっては全然FM音源にならないかもしれない!
まあそれもコンテンツとしては楽しいかしら。

とにかく、まずはサイン波をADSRで出すオペレータを一つ。

細かくは、中々うまい事扱えなかったvstguiで8bitFontを表示させる事に成功。
これはまた別のエントリで。

2016年10月21日金曜日

MDX解析で色々3:ADPCM

いよいよFM音源部分がある程度鳴るようになってきたので、ADPCMに手をつけないわけには
いかないのでありました。

しかし、ZMS用のドライバを作っている時には、一度挫折した経験のあるADPCM。
今回こそは!という気持ちで取り組みました。

PDXのフォーマットは超簡単で、こんな感じ。

[ポインタ]l + [$0000]w + [長さ]w ×96
[PCMデータ]

なので、ADPCMのデータは割とすぐに取ってこれる。それをそのままサウンドドライバに渡し
てもギャリギャリとノイズが鳴るだけ。

ググってもADPCMの資料は書いてある事が難しくて、更にX68用の資料はほぼ無いに等しい。

うーむ、これは困った・・。

そこで、誰かの作ったソースコードを探す事に。

しばらく探すと、一個だけあった!!

X68用のADPCMデータをWAVに変換して吐き出してくれるソースコード。

それを解析して、15600hzのWAVを作る事は何とかできた。
時間かかったけど。

そのまま44100hzのドライバに渡すとまあ当然のように短く高い音が鳴るだけで、想定通り
ではない。ではどうやって周波数をアップサンプリングするのか。

ググったらこんなの出てきた。

各サンプルの後に  個の0を追加するということである。

wikipediaの「サンプリング周波数変換」から引用しました。

これ読んでびっくり!!ええ!?引き延ばして間にゼロを入れるの!?

これは流石に自分の波形弄り人生でもすごい違和感を覚えたので、引き延ばした後は
直前のデータをそのまま入れるというアップサンプリング方法を考える。
でも具体的なコードが思い浮かばない。結構何日も考えたけど思いつかず。

そしたらある日、夢の中で突然思いつく!超シンプルな方法を!!

朝起きて急いでコーディングしてみたら、鳴った!!ある程度想定通りの音が!!
すごいね~夢作曲とかあるけど、夢コーディング。プログラマの皆さんだったらふつうの事
かしら?

その考え方がこれ。

2.826923076923077 = 44100 / 15600

15600hzのデータを取ってくる時に、この数字で割って、intでキャストすると。
わー、結果だけ書くと超簡単やないかい!!何か恥ずかしいくらい簡単!!

そうすると44キロのデータになるという流れでした。

でもこの方法で引き延ばすと、高域にすごい変なシャカシャカが出るので、ローパスフィルタ
を通して鳴らすと中々イイ感じの音になりました。

こうしてMDXはある程度鳴らす事ができるようになったのでした・・。

2016年10月20日木曜日

MDX解析で色々2:ピッチ関連

というわけで、少しづつ鳴り出したMDX。

繰り返し処理なんかは良く考えられていて、鳴らす方はあんまり何も考えずにやっても
すぐに繰り返しできたし、そういえば最大のネックの一つだった全体ループも割とすんなり。

このまま調子よく行くかと思いきや、ピッチ関連でどハマりしたのでした。

実際、現在の状態でもあんまりちゃんと鳴っていないポルタメントO。
これはこんな感じになっております。MDXフォーマットから引用。

・ポルタメント
    [$F2] + [変移※1]w
        変移 = 1クロックあたりの変化量

ポルタメントはシンプルなんだけど、1クロックあたりにどんだけピッチが動くかが入ってる
って、これ誤差でまくり仕様じゃないの!?と思ったらやっぱりそうでした。厳密に計算
すると、全く想定通りに鳴らない!

なので考え方を変えて、当時の整数計算を意識してざっくりとやりだしたらある程度うまく
いきました。でも未だに変な挙動アリ。


そしてLFOはこんな感じ。

・音程LFO制御
    [$EC] + [$80]b    MPON
    [$EC] + [$81]b    MPOF
    [$EC] + [WAVE]b + [周期※2]w + [変移※1]w

        WAVE0 [ 鋸波 ] : 周期 = 設定値×4 : 変移 = 設定値×周期÷512
        WAVE1 [矩形波] : 周期 = 設定値×2 : 変移 = 設定値×256
        WAVE2 [三角波] : 周期 = 設定値×2 : 変移 = 設定値×周期÷512

・LFOディレイ設定
    [$E9] + [???]b    MDコマンド対応

これはしょうがないので、本家の動きをキャプチャーして、自分でざっくり作ってみて、
比べてみるというかなり原始的な方法で作ってみました。これはこれで何だかうまく
いってるのだかいってないのだかよくわからない感じに。

雰囲気で勝負という結果となりました。でもここもたっぷり時間がかかったなぁ・・。

つづく~

2016年10月18日火曜日

MDX解析で色々1:タイマーB

というわけでMDX一区切り。

2016年に一生懸命MDXの解析とかやってる人は世界に俺だけかと思う位情報が無かった。
ググっても大体2000年代が最新情報。フォーマットに関しては2つほど資料が落ちてたので
それを使って1バイトづつ読み込んで解析していきました。

■タイマーBって何や
MDXはBPMやTEMPOで制御するのではなく、X68の割り込みタイマー、通称タイマーBという
割り込みを使うのだ。この辺も未だあやふやなままだが、このタイマーBの数値でカウンタを
回して、カウンタの数字を見ながら音を鳴らすというのが大きな流れだ。

まあ当然ながら、このタイマーBでハマった・・。

テンポとタイマーBの1対1の数式は2~3個あったソースコードから引用できたので問題無い
のだけど、ZMSは最初に曲全体を絶対的な時間にどんと割り振ってから演奏するやり方を
採用していて、まあ理由はWindowsの割り込みタイマが信用ならんからなんだけど、その方法
をまずは採用して計算してみた。

でも途中でテンポが変わる時にもう計算がレロレロに・・。

しばらくそのやり方で作っていって、だいぶ鳴るトコまで来たのだけど、どうにもダメなトコに
ブチ当たって、完成間近と思われていたMDXを一度リセット!!

これが当ブログ9月5日の事でありました・・。

■絶対時間を止める
カウンタを厳密に回す方法が中々見つからず、色々やってたら、ナイスな方法をようやく
見つけた。それがこれ。この計算を、10msとかの間隔で呼び出す。

// 経過時間取得
LONGLONG llNow = GetNowHiPerformanceCount();
LONGLONG llPassTime = llNow - g_llPreTime;
g_llPreTime = llNow;

// 1クロックの計算はテンポチェンジに備えて毎回やっておく
double dWholeNote = (6.0 * 2048.0 * (256.0 - (double)g_fTimerB)) * 4.0;
g_dOneClock = (dWholeNote / 192.0);

// 経過時間が1クロックの時間のどれくらいかを計算してクロックに足す
g_dClock += ((double)llPassTime / g_dOneClock);

カウンタ計算の度に、クロックがどのくらい進んだかをdoubleで計算する事に。そして
使うときにはintでキャストするというやり方。

これでどのくらいちゃんと厳密にできてるか調査してみたら、ほぼ想定通りの数字が出た。
良かった!!これでクロックが増える度に命令を取り出してきて実行するといういきあたり
ばったりのやり方で行ける!

■いきあたりばったり
そういう意味でも、いきあたりばったり方式はX68時代のやり方とほぼ同じであり、再現という
意味でもいい感じになってしまいました。このクロックカウンタ計算をベースとして作り出したら
割とトントンっと進みだしたのでした。

つづく~

2016年10月14日金曜日

MDXひと段落

結構時間をかけてやってしまっていたMDXフォーマット解析。
ようやく今週になってまあこんな所だろうという感じになってきた。

ZMSを鳴らすアプリに組み込んで、ZMSもMDXも鳴るよという体裁に
落ち着くことができた。

この1~2カ月、色々あったなぁ~。

以前作ってたMDXのコードは全破棄して組み込んだのだけど、
不完全だったのでバッサバッサとコードを削除する時はやっぱり
気持ちイイね~!

忘れないウチに何にハマったのかのメモをここに書いていく事にしよう。

やはり割り込みのイミュレーションとピッチ制御かしら。

後は意外とまあまあの所に軟着陸できたadpcmかな。

この辺りをまとめます。
誰か検索で当たってこないかな~。
MDXの話で盛り上がりそう~。

2016年9月5日月曜日

MDXというノスタルジー

ここんとこずーっとやっていたMDX。

MDXとは、X68000時代に一般的に使われていた音楽データのフォーマット。

僕が使っていたZMSよりもはるかに多いユーザーが作ったり聴いたりしていた。
そのデータはその頃のゲームのBGMを吸い出したり耳コピしたりして作られており、
今でもWindowsでプレイヤーとデータがあれば普通に聴ける。

YSだったりドラスピだったり正に青春時代ど真ん中の楽曲がそのまんまな感じで
聴けるMDXはいつ聴いてもワクワクする。

というわけで、現在作っているZMSのドライバでもMDXが読み込んで鳴らせたら
それはイイ感じにならない?という安易な気持ちで取り組みスタート。

まあデータ容量の少ない時代のフォーマットなのでシンプルで特に複雑な事は
何もないと勝手に踏んでやり出したのだけど、ZMSとの違いを吸収する為に
専用コードをドバドバと書き出したらもう滅茶苦茶になってしまった。

特に!!

テンポが曲中で変わる曲はそもそも自分のドライバでは対応していなかった事が
判明して、それを吸収する為にMDX用の演奏部分まで作成する始末。

気が付くと、ほぼZMSとは別のコードで鳴らす羽目に。
しかも中々思った通りに鳴らない。FM音源部分も手を入れないといけない。

そして夏イベや担当PJなどをこなす為にしばらく離れていて、そろそろやるかと
戻って来たところ、色々と限界が見えてきた。

やはり、完全に別物として作った方が良さそうだし、ノスタルジーやロマンの部分
なので力を入れる理由も見当たらなくなってきた感じ。

一旦区切りをつけないとなと思いつつ、ここまで作ったので惜しいという気持ちも。

しばらくはゆらゆらと悩み揺れる状態だろうか・・。

2016年3月9日水曜日

MID2MMLは諦める・・そしてMMLで和音対応

色々やるも、そこそこの変換精度でMIDIをMMLに変換されるようにはなった。
だが、あまりそこに力を注いでもしょうがないかな?という気分になってきた。

というのも、現在のゴールは自作曲のMML化であり、サンプルに使っている
のはドラスピのMDXをMIDIに変換したもので、一度変換したものをまた変換
するというのは余りにも効率が悪いのである。

少しづつ自作曲をMML化し始めた所、手打ちのMMLが最もキレイで効率的
な事がわかってきて、一旦MID2MMLは諦めることにした。

そして次はMMLの強化である。

MMLは1トラック1ポリという流れは当たり前であり、和音ナド対応しないのが
普通であった。MIDI機器の登場により、場当たり的に対応はされていたが、
そこに触れずにMMLから去ってしまった経緯もあった。

お手本としているZMUSICを見ると、和音の表記方法はアポストロフィで囲む
というやり方らしい。この方法だと理論的にはあらゆる和音が表現できそう。

しかし、MMLを読み解く側からいくと、ものすごく大変なのだ!!

具体的には、和音のタイ関連。

1.単音から和音へのタイ
2.和音から単音へのタイ
3.和音から和音へのタイ

こういう場合が出て、さらに、3の場合でもドミソからドファラに繋ぐ場合、
ドはそのまま発音し続け、ミソをノートオフし、ファラは発音、最後に全ての
音をノートオフとしなければいけない。

これの実装にハマった・・。2~3日くらいかかったかしら。

自作曲を放り込んでは聴いてみてバグを潰すの繰り返し。
なんとか自作曲がちゃんと鳴るようになった。

MMLはMIDIから変換せずに手打ちがやっぱり良い。

これで一通り自作曲をMMLから鳴らす事ができるようになったので、次はゲーム
的アプローチのアプリを作成していくことにしている。現在仕様策定中。

2016年3月1日火曜日

MMLとの戦い

FM音源のVSTインストでドラゴンスピリットのジャングルの曲を作ってみた。
MDXからMIDIにコンバートして、CUBASE上でエディット。

さすが名曲、ちゃんと鳴るまで色々と工程は必要だったけど、キモチのいい
音になって満足。

そして、次の工程、にせぱんの新曲をFM音源でMMLで発表という誰得な
ものではあるが、それをやろうと決めたので最後まで頑張る。

MMLをイチから起こすのもいいが、せっかくだったらMIDIからMMLに変換
できて、それをエディットした方が効率的な気がした。今後も新曲をその
方式で発表というのも面白い・・かな?誰得な話ではあるが。

そこで、MIDIを読み込んで、MMLを吐くコンバータ作成中。

まだデロデロの演奏ではあるが、大きくは鳴るようになってきたので、
忘れないウチにハマりポイントをメモる。

■音長が全て
音階はすぐに表現できる。

char cNoteTbl[12][3] = { "c", "c+", "d", "d+", "e", "f", "f+", "g", "g+", "a", "a+", "b" };

こんな感じでテーブルを用意して、ピッチの値を12で割ってオクターブを出して、
余りをこのテーブルに当てはめればすぐに出る。これは簡単。

しかし!音長を表現するのがものごっつい大変!!

MIDIデータは絶対時間ではなく、デルタタイムの積み重ねなので、一つデータ
を見落とすだけで後ろが全部ズレるのである。現在はズレズレである。

問題は、ノートオン→ノートオフの繰り返ししかないので、それをMMLで表現
しようと思うと、一音鳴り終わって、次鳴る時にしかMMLを吐けないのだ。

1.音が鳴った
2.音が鳴り終わった←ココではまだ表現できない
3.音が鳴った←ココで初めて1と2の評価をする
→3の音が鳴った時に全部音符でいいのか、休符を伴うのか、調査する。

※CUBASEがスタンダードMIDIファイルを吐く時、常に480の分解能で2tick程
短く発音するようになっているのだ。なんだこの仕様は!!例:480→478

これがハマりポイント!!

デルタタイムはどのように表現してもいいけど、MMLは4分音符などの音符で
表現するので、そのままストンと変換できない!!難しい!!!

そこで、以下のテーブルを作ってみた。

char cLengthTble[22][5] = {
"1", // 4.0
"2.", // 3.0
"2", // 2.0
"4.", // 1.5
"3", // 1.3333333333333333333333333
"4", // 1.0
"8.", // 0.75
"6", // 0.6666666666666666666666666
"8", // 0.5
"16.", // 0.375
"12", // 0.3333333333333333333333333
"16", // 0.25
"32.", // 0.1875
"24", // 0.1666666666666666666666666
"32", // 0.125
"64.", // 0.09375
"48", // 0.0833333333333333333333333
"64", // 0.0625
"64",
"64",
"64",
"64"
};

4分音符を1として、他の音符の割合だ。一番細かい音符は64部音符にしたけど
これが現在のバグの原因かもしれない・・。

このテーブルを使って、音や休符の長さを少しづつ削ってやることにした。そう
して、何となく表現ができるようになってきた。

でも、サンプル曲などを変換するとズレズレになってしまう。これは現在原因を
調査中である・・。

2015年6月10日水曜日

Windows:vstでFM音源鳴った・・

VSTのホストを使って、VSTインストを鳴らすってトコは割りとすんなりいった。
そこで、欲が出て、X68sound.dllの置き換えができるVSTinstが作れないか?というのが前回まで。

早速、FM音源とは何か?という勉強を始める。
ネットには、正直ほとんど資料は落ちていない。

FM音源の曲データを作るのはまだちょっとはあったけど、FM音源そのものを作りたい
という人は全くいないらしい。わはは。

もうしょうがないので、ちょろっとある資料を元に原理を調べてみる。

ふむふむ、まず、サイン波で音を鳴らす時、あの波が1秒間に440回だと、
「A」つまりラの音が鳴るという事がまずベース。

そこに、別のサイン波の音を畳み込んで計算すると、音が変調されて、
あの例の音になるらしい。

実際に、サイン波に別のサイン波を畳み込むという計算方法がまずわからなかった。
具体的には、簡単に書くと、

sin(2.0 * PI * 周波数)

これでとりあえず周波数のサイン波が出る。
畳み込みするためには、このカッコの中に、前のサイン波の結果を入れるのだ。

sin( sin(2.0 * PI * 周波数1) + (2.0 * PI * 周波数2))

こんな感じ。これで周波数1がモジュレータ、周波数2がキャリアとなる。ここまでは、
正直、すぐにできた。でも、FM音源独特のギョイ~~ンという感じにはならない。

■困った時は神様に頼る
というわけで、世の中に落ちていたソースを使って何がおかしいのかを探る。
x68sound.dllがビルドできたし、その他にもFMGENというソースも見つかった。
この2つのソースを行ったり来たりして解析を進める。

ADSRを自作してみた。しかし、目指すFM音源のADSRはものすごく特徴的で、
簡単な計算では全く似てこない。神様はやはりテーブルを作成していた。

ここで、powとかexpとかの使い方でハマった・・。
今でもよくわかんないけど、この辺りの関数をしっかり使うのが必要。

■ちゃんと計算したらダメ
やはり20年も前の技術なので、今の64bitの環境でヌルっと計算しても、あの感じ
にはならない。出来る限り再現したかったので、神様のソースに頼る。

■もうダメかと何回も思う・・
何度やってもいい感じにならないので数回諦めかけた。そこで何かひらめいて
次やってみたらちょっと進む、の繰り返し。もうたくさん躓いたので何か覚えてない!

とにかく、神様のソースを百回以上読んで、頂ける所はコピペ。自分で作る所は
自分で。あっちゃこっちゃガチャガチャやってたら、さっき、何とか鳴った!

ギョインって鳴った!

どうしてギョインって鳴るのかわかんないけど、とにかく鳴った!よかった!!

自作VSTinstに組み込めたので、今後は、

・オシレータをサイン波だけじゃなく、矩形波、三角波、ノコギリ波なども入れたい。
・エフェクターを入れ込みたい。
・現在リズム感が悪いので、チャキチャキと鳴らしたい。

この辺りを狙っております。いけるかな・・。


2015年5月26日火曜日

Windows:FM音源はほぼ終了

怪しい所はあるにはあるが、FM音源周りに関しては以前のデータが同じ感じで
鳴るようになってきた。長かった・・。

■繰り返しの恐怖
|: |:cdefg:| gfedc:|
なんていう繰り返しのネストが可能だったのをだいぶ後に気づき、
ネスト対応にする為にえらく苦労した・・。ハマった。
・相対的に指定する
・ループエンドを見つけたら前にたぐってループスタートを見つける
この2点を思いついたら意外と少ないコードで実現できた。よかった。

■オクターブの恐怖
よくわかんないが、繰り返しの中でオクターブの上下をしても、
繰り返しから出たら元通りになるという仕様を発見。なんだこれ。
これも悩みに悩んだけど、繰り返し展開のスタート時にオクターブ
をセットするということを思いついて、なんとかなった。

■ポルタメントとLFO
ピッチ問題は後にひきまくって、数日かけてめちゃくちゃになって
しまった。ハマった。

そこで、
・オクターブと音階とKF
はOPMに寄り添わず、独自の方式で運用し、最後の最後に
独自方式からOPM対応方式に変換するという方法を思いつき、
作ってみたら意外とサックリいけた。

この方式を採用後、ピッチ関連のポルタメントとLFOが実現可能に。

ポルタメントは数日かけて悩みまくったがなんとか鳴るように。

LFOは耳コピ的に同じ数字を入れたらいい感じっぽくなるように。
sin()を使う所で結構ハマった。

sin((DX_PI / 120) * 経過時間 * 波の幅)

これでうにゅうにゅとLFOがかかるようになった。

とにかくピッチ関連はハマった。

■adpcm沼
半日くらいかけて検証してみたが、どうにもadpcmが鳴らない。

ZPDデータをバラして、一つ一つのPCMにしてファイルセーブ、
PCMをWAVに変換、WAVをOGGに変換、OGGをリストにして
読み込み、ノートデータから鳴らすということはできたので、
とりあえずめんどくさいが曲を鳴らす事は可能になった。

しかし、adpcmをそのまま鳴らしたい!という欲求が出て、
ひたすら検証をしてみた。

・普通に鳴らすと、ちょっとだけ鳴ってすぐに音が切れる。
・同じコードをコマンドラインでビルドして試した所、普通に鳴った。

そこで、DxLibが何かしてるのかと思いDxLibの息のかからない
所で鳴らしてみた。やっぱりダメ。

今の所、ウィンドウズアプリとしては僕の実力では鳴らせない。
コマンドラインのアプリだったらいけるのに。なんでだー!!

2015年5月15日金曜日

Windows:FM音源鳴ってきた

ZMSのパーサーをじっくりと作りつつ、ようやくFM音源が鳴りだしてキタ!

今覚えているウチに「えーそうなの!?」みたいのを覚書しておこう!

■音色設定方法
音色の設定方式は、通常形式と、AL/FB分離形式というのがあるらしい。
FM音源使ってた時は、分離形式しか使ってなかったので、通常形式は
記憶の彼方に飛んでいっていた。しかし、OPMに書き込む為にはここは
避けては通れない。

AF(フィードバック/アルゴリズム) = (FL(フィードバックレベル)*8) + CON(FM operator connection)

という形でAFを作ったり、直接3bitづつFLとCONを書き込んだり。

まあ、分かれてる方が音が作りやすいわね。なんで一つになってたんだろ?

■音程がわかりにくい
X68kFM音源の神、GORRYさんがTWITTERで言っていた。

4MHzのYM2151にデータシート通りの音階を設定すると「3半音-8セント」ほど高い音が出る(Cを出したつもりがほぼD#の音階で鳴る)ので、そこはドライバ側で吸収する必要がある

ここをきっちり「3半音-8セント」で計算しないで「3半音」で計算して、8セントはデチューン命令でゲタをはかせて与えるという実装もそこそこある。うちのドライバが「^20(=8セント)が標準」だったのはそういう実装

ちなみにこの「3半音ずらす」ときに「単純にKCレジスタ設定値から3引く」と正しくない。KCレジスタに与える音階値は0-2,4-6,8-10,12-14だけが有効で、3,7,11,15は無効値なので

どうも、YM2151への供給クロックが、業務用3.579MHz / X68000用 4.00MHz
というような歴史があるらしく、その辺もしっかりとイミュレートしているx68sound.dll
なので、その通り音階を入れてあげないといけない。ここは面倒くさくてハマった。

なので、CとDは音程が狭い。なんだこれ。

■マルチメディアタイマーの発見
かなり正確に指定msecごとにCALLBACKしてくれるのがWindowsにあるらしい。
早速使ってみたら、いい感じ!!invokeの時は60分の1秒でしか色々できなかった
ので、結構ズレまくってた。

それでも16msecごとなんだけどね。描画があったりで時々ガッっとズレてた。絵は
少々ズレてもカ・ワ・イ・イでなんとかなったけど、音は流石にズレるとしんどい。
最近捨てたT3exのシーケンサーを思い出す。小節ごとにグっと待ちが発生する
ナイスなシーケンサー。

■繰り返し
これがハマった!!繰り返しの実装は本当に大変だった・・。ZMSでは簡単に

|:16 cdefg :|

なんて書けちゃうけど、これを実現するのは本当にめんどくさい!!ズレるのが
嫌だったから、イベントは絶対時間で持っておいたので、絶対時間の足し込みが
すげーめんどくさかった。でもなんとかなった・・かな?