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

2019年7月11日木曜日

整数PCMと浮動小数点floatの変換ナド

現在作成使用中の波形編集ソフト、wavcalc。
コンセプトとしては、
・簡単に波形が編集できる
・内部演算は32bitfloatで行う
この辺りである。

内部演算を32bitfloatで行うという事は、PCMデータはイチイチfloatに変換する必要があり、
そのやり方があやふやなまま運用してきていた。

ココにきて、そろそろリリースかという雰囲気になってきたので、あやふやなままではアカン
と思い、しっかりちゃんとやろうという気分で取り組んでみた。

ポイントとして表を作ろう
解像度最小無音最大
8bit0
(0x00)
128
(0x80)
255
(0xff)
16bit-32768
(0x8000)
0
(0x0000)
32767
(0x7ffff)
24bit-8388608
(0x800000)
0
(0x000000)
8388607
(0x7fffff)
32bit-2147483648
(0x80000000)
0
(0x00000000)
2147483647
(0x7fffffff)

ここで今まで適当だったのが、負の段階と正の段階はが各1ずつ違うという所。
16bitを例に取ると、負は32768段階あるけど、正は32767段階なのだ。

これをそのままfloatに変換すると、floatは-1.0~0~1.0なので、おかしな事になる。

今までは0.5足して32767.5で割るというやり方がネットにあったのでそれでやっていたが、
0が0にならない、というモヤモヤした状態で変換していた。
これは音にはそんなに影響無いけど、なんかキモチワルイ。

そこで実験。市販の波形編集ソフトを起動して、どうやって変換しているのか調べてみた。

そしたらなんと、驚愕の結果が!!

wavelabとsoundforge、両方とも、32768段階で正も負も計算していた!!!!

という事は、例えば16bitだったら、32768段階なので、最小単位は0.0000305175781となり、
負の最小は-1.0、正の最大は0.999969482という事になる。

これすげーショックな結果!!

でも、よく考えると、音割れするよりはそっちの方が良いのかしら・・と思いなおしたり。
それでも普通に普及している整数PCMって、イビツな状態だったのよね・・。
何だか納得いかないわ・・

2016年11月17日木曜日

発音キッカケをtickに変更

曲の途中でテンポが変わるデータを演奏するとヨレヨレだったZMS。

MDXでは既に実績のあった、テンポに合わせてカウントされるタイマを使って
演奏させるように変更を行った。

今までは曲スタートからの実時間をビッチリ計算していれていたのを、
全音符の分解能192でカウントするスタイルに。

通常のMIDIは分解能480なので2.5分の一くらいのショボさ。

結構大規模な改修だったので、しばらく時間がかかるかなと思ったら、
半日ぐらいでツルっといけてしまった。

やはりMDXでの実績が効いた。

実際にならしても依然と同じように鳴ってくれて、テンポが変わるとちゃんと
追従する。イイ感じ。

以前より鳴らし方も非常にシンプルになったし、元々CUBASEとかもこの
スタイルでデータ管理してる感じだし、なんで早くこれにしなかったんだろう。

2016年9月5日月曜日

MDXというノスタルジー

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

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

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

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

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

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

特に!!

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

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

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

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

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

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

2016年6月29日水曜日

続:レイテンシー問題

前回レイテンシー問題が発生したPCで再度レイテンシーの内容を確認中。
前に出ていたレイテンシーが全然出てこなくなる。

な、なんで・・!?

というわけで、普通にレイテンシー無くプレイできた。
会社の同僚にプレイしてもらって感想をもらう。
中々良い反応だったのである程度満足。

ただ同時に先の無い企画である事にも気づく。

もう少し手元にあるPCで問題が出なければリリースしてしまうか・・。
悩む・・。

2016年6月24日金曜日

レイテンシー問題勃発

ほぼほぼ最初の構想通りのプログラムが出来上がってきたので、プレゼンの準備
の為に別のPCにインストールして動かしてみた。

すると!

音とマウスをクリックするべきタイミングがズレている!
その状態でゲームを遊んでも、先に進まないし、全然楽しくない!!
そりゃそうだ、音に合わせてクリックするゲームだから。

これは困った・・
世の中のPC全部に合わせて調整するのなんか不可能だし。
たまたま自分の持ってるPCがタイミングが合ってただけだったんだなぁ・・。

使っている技術がかなりニッチなので、ググっても中々これというのが出てこない!

VSTインストを使って、VSTホスト的な状態で、Dxlibを使って、レイテンシー問題に
ぶち当たっている人、いるわけないか~~~~~

これは問題の切り分けをしていく必要があるし、調査にも母数がいりそう。
実際、そんなに沢山の種類のPCが手元にあるわけでは無いし、ほんと困ったわ。

どうやって調査するのがいいのだろうか・・。

CRIは画面を光らせてタイミングを取ってたので、そういうサンプルプログラムを
作る必要があるのかしら。

となると、もし自動で検出できなかったら、アプリが始まるとまずズレの調整を
プレイヤーにしてもらってからになるのかな。めんどいわそんなゲーム。

いやー、根本的な部分なので激しく困った!!

しばらくはこの問題に取り組む必要がありそう・・。
これクリアーしないとプレゼンもできない!

2016年3月17日木曜日

波形を画面に出す

現在作成中のアプリ、ミュージックプレイヤー部分に波形表示がさせたくなった。
巷のDAWのような雰囲気とまではいかなくとも、どんな波形が鳴っているのかが
目視できるのは非常にありがたいし見た目も良いハズ。

ということで、波形データを取得して画面に出してみるものの、ただ単にそのまま
データを画面に出すのは超簡単。

しかし!!

画面に収める為に、波形を小さくして出すのが難しい!!
要するにデータの間引きが難しいのだ!!

これはハマったし、未だこれだという所まで来ていない。

単純に途中のデータを飛ばして読んできて出すというやり方でもOKだが、周波数
に偏りのあるものは変な形になってしまうことも。

そこで、飛ばす時にそこまでの最も大きいまたは最も小さいモノを表示する事に
した。これで詳細はともかく、波形の雰囲気は割りと出せるようになった。(でも、
拡大のパラメータによっては、波形の上と下のバラつきに偏りがすごく出る。)

そして、リアルタイムに波形を扱う時は、波形データをそのまま触ると爆裂に時間
がかかる。フレームレートが2とかになる。

そこで、WAVを読み込んだら、読み飛ばした波形表示専用のデータを作成しておく
必要がある。DAWや波形編集ソフトもやってますな。これをやると高速に表示が
可能なのであった。

あたりまえのようなこれらの話、たどり着くまで時間はかかったのでした・・。

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年7月9日木曜日

フィルターって一体何!?

こうやってシンセを設計してみて、今までシンセについて何もわかっていなかった事がわかった。

手本となるシンセのパラメータを細かく分析してみて、このパラメータってこういうことしてるの!?
と改めて発見する。

今までほんとになーんにもわかってなかった!!

■フィルターって何!?
アナログ的シンセに必ずあるフィルター。
自分で実装してみて、初めてわかったことがあった。
フィルターにADSRナド、エンベロープジェネレータがあるけど、
それはなーんとなく使ってて、何が起きてるのかよくわかってなかった。

カットオフはある周波数から上か下、又は周りをそぎ落としてるんだよな・・
レゾナンスはそのあたりを強調してるんだよな・・
ADSRはそれが時間とともに効いてくるんだよな・・←ココ間違い

くらいかしら。そんな曖昧な感じしか持ってないままフィルター実装したら、
何だか音が違う。思った感じにならない。

そう、ADSRは時間と共に効いてくるんではなくて、
「時間と共にカットオフの周波数が変化している」
が正解でした。(他の実装もあると思うが)

だから思ってた音にならんかったんや!
結構ADSRをFM音源部分と揃えることに時間をかけたけど、何も意味なかった!!

これから作り直し。

■コーラスって何!?
神様の作ったサンプルを元に実装してみたけど、全く思った感じの音にならない。
瞬間的にそれっぽい時はあるけど、パラメータを動かすとすぐに変な音に。

そこで、各パラメータを掘り下げていくと、パラメータによって、「おいしい」数値
というのが存在するっぽい事がわかってきた。

今まで、プリセットをカチカチと変えて微調整の人生だったので、これまたすごい
衝撃。そうだったのか~的な。

そして、今でも全然わかってない。
音の世界は深い・・。

2015年7月1日水曜日

Windows:VSTにpng使いたい!

GUI作り、壁にぶつかってはちょっとだけ進み、を繰り返しております。

そろそろレイアウトもいい感じになってきたので、透過PNGが使いたい所。
神様の作ったサンプルは全部BMPなので、ファイルサイズも無駄にでかいし、
いい機会だし取り組みました。

神様もさらりと書いております。pngが使いたかったら、zlibをビルドして、
libpngをビルドして、USE_LIBPNGを入れてこうするといけるよ!みたいな。

さらりと書くよねー。さらりと書いてあるから簡単にいくかなと思ったら全然
うまくいかなかった。ハマった。

神様の言うとおりにしてたらダメだったので、自分でやったことをメモる!

■ソースはwebから落としてきてビルドしたらダメ

zlibやlibpngの専用サイトから落としてきてビルドしたらダメだった。じゃあ
どうするかっていうと、VSTSDKの中の、vstguiの隣にあるzlibフォルダと
libpngフォルダの中にあるソースを使うのです。(正確にはvstgui.sfの中ね)

これらを使ってスタティックライブラリとしてビルドする。ビルドはいつも
ウォーニングでまくるけどあっけなく通る。zlib.libとlibpng.libができあがる。

zlib.hとzconf.h、png.hとpngconf.hをコピーして自分のトコにもってきて、
ビルドする。エラーでまくり。良く読むとlibの追加の方法が良くわかって
なかった。

■ライブラリの扱いは適当ではダメ

・libのパスを通す
(構成プロパティ→VC++ディレクトリ→ライブラリティレクトリ)
・libそのものを明示的に追加する
(構成プロパティ→リンカー→追加の依存ライブラリ)

これが必要なのね!ここハマった。みんなわかってるから簡単に書いて
るんだもの。そして、ビルドしたらまたエラー。なんだかライブラリ内の
関数がカブってるみたいな。そこで、

・無視するライブラリを追加
(構成プロパティ→リンカー→特定の規定のライブラリの無視)

ここにMSVCRT.lib(Release)とMSVCRTD.lib(debug)を入れたらビルド通る。

※これ以外にもマルチスレッド指定とかやったけど関係あるのかしら・・

このやり方が合ってるのかどうかわかんないけど、とにかくビルドが通って
無事PNGを使う事ができた。背景画像が800kbから6kbになって感激!

2015年6月30日火曜日

Windows:vstgui:解決はいつもいきなり

独自の画像表示の方法がわからないので、テキストエディットでパラメータを表示
することにしていた。しかし、パラメータを変えてもテキストの中身を変える方法が
わからない。

また、プリセットを読み込んでも、スライダーやノブは変わるのに、テキストの表示
は変わらない。これは困った。

VSTinstからGUIの関数が呼べないのがネックになっていた。GUIを作るときに、

editor = new VstGui(this);

みたいにするんだけど、このeditorという入り口から自分の作った関数が呼べない。
これは騙し騙しやってるC++の継承とか仮想関数とかよくわかんないトコが原因
ぽくて、非常に困っていた。これまたハマった。

いろいろとググってみると、別の角度からいける感じがする。100msecごとに
呼ばれる「idle()」を使えばいいんじゃねーかと。

この関数、アイドリングの時に呼ばれるみたいなんだけど、これで常に最新の
パラメータを表示しておけば、結局パラメータを変更しても追随するし、いけそう。

コードをさらりと書いて実行。すぐに解決。

いやー、ものすごい長い時間ハマってたけど、解決する時は一瞬だなぁ・・。

懸念は、100msecごとにテキストをうじゃうじゃと書くのはパフォーマンス的にどうか
という部分くらいかな。でもこの方法以外になさそうだし、これで行こう。

2015年6月26日金曜日

Windows:VSTinstのGUIは情報少なすぎ

世の中にはVSTinstを作ろうなんてヒトは少数なんですかね・・。
とにかく情報が少ない!!少なすぎる!!

神様の作ってくれたサンプル以上の事をしようと思うと、英語のサイトを見る必要があり、
でも英語のサイトを見てもそんなに情報が落ちてない。

GUIなんかもう手探りもいいとこよ!!

CSlider,CKnob,COnOffButtonあたりはサンプルからなんとなく使えたけど、テキストを
出したりするトコとかは見よう見まねでやったらできた的な強引なプログラム!!

実行してみたら実際に出てきたのはいいけど、本当にこのやり方でいいのかしら。

■現在ハマってるところ
・スライダーとかじゃくて、画像を出そうと思うと、てんでやり方がわかんない!!
独自フォントを使って文字出したいのだけど、どうやってやるんだろ・・?

テキストエディットが一応あるので、いけるようになるまではこれで。

・Cknobのハンドルに画像を使用すると、角度が付かない。画像そのものが
その状態のままくるくると動く。世の中のノブって回したら回転するんだけど、
それってみんな独自でやってるのかしら?独自でやるにしても、画像を勝手に
出せないしましてや回転なんかどうやんのか全くわかんない!!

でも、ハンドル画像部分にNULLを入れたら細い白いハンドルが出てきた。
やりたい事と若干違うが(2ピクセルのラインにしたい)、しばらくはこれで。

■なんとなく形にはなった
思った感じではないが、独自のスライダーやノブが動いて音色をエディットできるトコ
まではいけるようになった。これで一度CUBASEとかに読み込ませてみようかしら。

■これからの課題
・見た目をもう少し頑張るか、音の中身をもっとがんばるか、その辺迷いドコロ。
→音の中身を頑張らないと見た目頑張ったってしょうがないのだけどね。

まだまだ手探りだ!!

2015年6月20日土曜日

Windows:すぐに解決

寝ようかと思って最後にちょっと・・とググったら、神様のサイトにしっかりとSDK3.6での
変更点が書いてあった。

引数を一つ消したらビルドが通った・・。

超簡単だった・・。ゲショーン・・。

Windows:VSTinstにGUIをつけたい・・

せっかくなので、VSTinstにGUIをつけて、他のホストアプリで音色作ったりとか
したくなってきたのでした。

いつもの神様の所からソースを拝借してビルドしてみるも、ビルドがうまいこと
いかない!!

GUIのクラスをnewする所で、

「抽象クラスをインスタンス化できません」

って出てくる。これ一体なんだべ・・。
その下には

「純粋仮想 関数 "CControlListener::valueChanged" をオーバーライドするものがありません」

って出てる。

うーむ、そもそも、VSTってスタインバーグの誰かが作ったクラスを継承して
チョイチョイと個別の部分を変えるとできあがるという作りになっているので、
その元となる所との相性の部分なのかい?よくわからん!!

大体、C出身でC++は見よう見まねで何とかなっている感じの作り方なので、
C++の継承とかよくわからんままやってきたツケがきているとも言える。

オーバーライドとか、抽象クラスとかをググるも、なんのこっちゃわからん・・

掲示板とか見ても、「valueChanged関数を必ず用意する必要あるよ!」とは
書いてあるが、しっかり用意してるし・・。

わーハマった・・。ホストについてる標準のGUIで何とか入力はできるけど、
せっかくだから自前のGUI作りたいじゃんね。

日本人の作ったサンプルは大体みた気がするので、次は結局外国の人の
サンプルを探しにいくか・・。前もこれで何とかなった事があった。でも今日は
もう頭が回らないのでネルーーーーーっ!!

2015年6月18日木曜日

Windows:DSP道奥深し・・

FM音源が鳴ったので、次はリズムがイマイチなのと、エフェクターかしら、ということで
まずはリズムを直す。

■リズムはあっけない感じ

神様のコードがウィンドウズのWaveマッパを直接叩くヤツだったので、コードがややこしいし、
コールバックでネタを取りに来るので外部要因でリズムが遅れたりする。これが原因だった。

そこで、Dxlibの隠し命令を使ってDxsoundに直接VSTからもらったネタを書き込む事にする。

10msecコールバックを利用して、441サンプルづつ書き込んだらとりあえず鳴った。

ADPCMが鳴らなかった代わりに作ってた自前のPCMを鳴らすヤツもそこに混ぜ込む。

これで綺麗にVSTとPCMがキッチリ鳴るようになった!
なんだかあっけない!!

■エフェクターに手を出す

そしてVSTinst内蔵エフェクターを用意することに。これもまた別の神様がソースコードを
どんとサービスで置いてくれてたので、ありがたく利用させてもらう。

フィルター関連は何とか鳴るようになった。3バンドEQとして使う事に。

そしてコーラスとディレイ。

ディレイも同じ神様が別のソースを用意してくれてたので、それを借りる。
ちょいちょいと修正は必要だがなんとなく鳴った。よかった。

コーラスは更に別の神様が置いてくれてたソースを利用するも、全く鳴らない!
これが結構ハマった・・。ディレイと同じ神様のソースを利用させてもらうも、
思った感じのコーラスでは無い感じの音。うーむ、これは後で気になったら
アップデートするか。

そしてリミッターを作る。

リミッターは誰もコードを置いてくれないので、しょうがないので自分で作る事に。
これがなかなかうまくいかない・・。スレッショルドを超えた音をスレッショルドに
置き換えるだけだと、バリバリとディストーションがかかる。そらそうやわな。
ディストーションと同じ考え方だもんな。

しょうがないのでコンプ的にあるレベルを超えたらゆっくりと音が小さくなって、
スレッショルドでしっかりと音を小さくするというネタを考えつくも、うまくいく時と
いかない時などが発生してイマイチのデキ。

余りここに時間を取れないと判断して、次に進む事に。

■インタフェースは必要だけどめんどくさくて地味

MMLからエフェクターを呼ぶ部分をコツコツと作る。とにかくこれは地味でめんどくさくて
何も楽しくないけど、必要なので一個づつ作る。

今後のVSTinstとしてGUIなど入った時用に、パラメータを全部floatの0.0f~1.0fの間で
作る。これは今はめんどくさいだけだけど、後で効いてくるはず。

特にハマる事なくいけるかなーと思ったら、dbと音量の変換でハマる。

volume = pow(10, db / 20);

これだけの事に数時間かかった・・。

そして次は周波数とパラメータの変換にハマる。世の中のEQを見ると、最低20hzぐらい、
最高20khzぐらいのパラメータな感じ。それを0.0f~1.0fに置き換えるのが難しい!!

これも山ほど時間かかって、以下のコードにたどり着く。

freq = pow(10, ((value * 56) + 30) / 20);

専用のコンソールプログラムを作ってコツコツと値を作ってみました。テーブル的には

// 0 31hz
// 10 60hz
// 20 114hz
// 30 218hz
// 40 416hz
// 50 794hz
// 60 1.5khz
// 70 2.8khz
// 80 5.4khz
// 90 10.4khz
// 100 19.9khz

こんな感じ、悪くないね。左の数字は0~1の100倍の数字。検索で辿り着いた人もよかったら
どうぞ使って下さいな。

■そしてMoog的VCFへの興味

インターフェースもデキたので、サンプル曲を試しにちょこちょこと作ってみて思う。
LowPassは確かにLowPassなんだけど、なんだか素っ気ない感じ。もっとシンセっぽい
レゾナンスギュビギュビの音が使いたい!!!という欲求がふつふつと。

ネットで調べてみると日本語は全滅。

英語のサイトでいくつかサンプルコードが落ちている。
一つづつ検証していく。

3つほど試してみたが、音が全く出ない!!困った・・
諦めかけた時、4つ目のサンプルが見つかる。

強引に修正して試してみたら、小さい音で鳴ってる!!おっ!やった!!
数値を百倍してみたらちゃんと音が鳴る!!すごい!!

ちゃんとMoogっぽいVCFになってるじゃん!!ギュビギュビいってる!!気持ちいい!!

こういのをココに転載するのってありなのかなぁ・・。
まいっか。誰かの役にたつかもしれんし。

※DFLさんがMUSICDSPにアップしてたものです。

■変数
double state[4];
double ix, ixfrac;
int ixint;
double freq, q, bw, gain, resonance;
double in1 = in2 = in3 = in4 = 0.0f;
double out = out1 = out2 = out3 = out4 = 0.0f;
double moogq = moogp = 0;
double state[0] = state[1] = state[2] = state[3] = 0.0f;
■初期化
// setting pole coefficient based on frequency
double fc = 2 * freq / samplerate;
double x2 = fc*fc;
double x3 = fc*x2;
moogp = -0.69346 * x3 - 0.59515 * x2 + 3.2937 * fc - 1.0072;
// setting Q
ix = moogp * 99;
ixint = (int)floor(ix);
ixfrac = ix - ixint;
■毎ループ
// MOOGフィルターの計算
in = in / 100;
out = 0.25 * (in - out); //negative feedback
double temp;
moogq = resonance * crossfade(ixfrac, gaintable[ixint + 99], gaintable[ixint + 100]);
for (int pole = 0; pole < 4; pole++) {
temp = state[pole];
out = saturate(out + moogp * (out - temp));
state[pole] = out;
out = saturate(out + temp);
}
out *= moogq; //scale the feedback
return out*100;
■必要なテーブルと関数
// クロスフェード
static inline double crossfade(double amount, double a, double b) {
return (1 - amount)*a + amount*b;
}
// サチュレート
static inline double saturate(double input)
{
double x1 = abs(input + 0.95);
double x2 = abs(input - 0.95);
return 0.5 * (x1 - x2);
}
static double gaintable[199] = {
0.999969, 0.990082, 0.980347, 0.970764, 0.961304, 0.951996, 0.94281, 0.933777, 0.924866, 0.916077,
0.90741, 0.898865, 0.890442, 0.882141, 0.873962, 0.865906, 0.857941, 0.850067, 0.842346, 0.834686,
0.827148, 0.819733, 0.812378, 0.805145, 0.798004, 0.790955, 0.783997, 0.77713, 0.770355, 0.763672,
0.75708, 0.75058, 0.744141, 0.737793, 0.731537, 0.725342, 0.719238, 0.713196, 0.707245, 0.701355,
0.695557, 0.689819, 0.684174, 0.678558, 0.673035, 0.667572, 0.66217, 0.65686, 0.651581, 0.646393,
0.641235, 0.636169, 0.631134, 0.62619, 0.621277, 0.616425, 0.611633, 0.606903, 0.602234, 0.597626,
0.593048, 0.588531, 0.584045, 0.579651, 0.575287, 0.570953, 0.566681, 0.562469, 0.558289, 0.554169,
0.550079, 0.546051, 0.542053, 0.538116, 0.53421, 0.530334, 0.52652, 0.522736, 0.518982, 0.515289,
0.511627, 0.507996, 0.504425, 0.500885, 0.497375, 0.493896, 0.490448, 0.487061, 0.483704, 0.480377,
0.477081, 0.473816, 0.470581, 0.467377, 0.464203, 0.46109, 0.457977, 0.454926, 0.451874, 0.448883,
0.445892, 0.442932, 0.440033, 0.437134, 0.434265, 0.431427, 0.428619, 0.425842, 0.423096, 0.42038,
0.417664, 0.415009, 0.412354, 0.409729, 0.407135, 0.404572, 0.402008, 0.399506, 0.397003, 0.394501,
0.392059, 0.389618, 0.387207, 0.384827, 0.382477, 0.380127, 0.377808, 0.375488, 0.37323, 0.370972,
0.368713, 0.366516, 0.364319, 0.362122, 0.359985, 0.357849, 0.355713, 0.353607, 0.351532, 0.349457,
0.347412, 0.345398, 0.343384, 0.34137, 0.339417, 0.337463, 0.33551, 0.333588, 0.331665, 0.329773,
0.327911, 0.32605, 0.324188, 0.322357, 0.320557, 0.318756, 0.316986, 0.315216, 0.313446, 0.311707,
0.309998, 0.308289, 0.30658, 0.304901, 0.303223, 0.301575, 0.299927, 0.298309, 0.296692, 0.295074,
0.293488, 0.291931, 0.290375, 0.288818, 0.287262, 0.285736, 0.284241, 0.282715, 0.28125, 0.279755,
0.27829, 0.276825, 0.275391, 0.273956, 0.272552, 0.271118, 0.269745, 0.268341, 0.266968, 0.265594,
0.264252, 0.262909, 0.261566, 0.260223, 0.258911, 0.257599, 0.256317, 0.255035, 0.25375 };

2015年6月4日木曜日

Windows:VSTホスト作成メモ

FM音源を鳴らす要領で、VSTインストを鳴らしてみたら、割りとちゃんと鳴った。
そこで細かくハマった所があったのでメモ。

■MIDIに頼ってもダメ
VSTiにMIDIデータを送れるっつーんで、ノート情報以外のを送ってみたけど、
うまく対応してくれるのと、そうでないのがある。そこで、ボリュームやパンは
結局自分で作る事に。

VSTiが送ってくるサンプルの大きさをいじって実現。

線形でやると全然音量的にはリニアにならないけど、元々のFM音源の方が
そうだったのでそのまま放置。データ作るようになってやっぱり必要だったら
例のlog10を使った奴を使うか・・。

■バスの作成方法わからず
神様の作ったサンプルは一つのVSTiをそのままウィンドウズのWAVEマッパ
に送るだけの超シンプルなもので、2トラック以上を実現しようとすると、何か
手が必要だった。

クラスを配列化して、スロットを作り、そこにVSTiをはめるトコまではまあ色々
あったけど何とかなった。

その次、音を混ぜるのってどうやるの!?ってトコでハマる。

色々と調べてみると、単純に、バッファのデータに次のデータを足せばOK
という事にたどり着く。えー!?そんなんでいいの!?

実際やってみたら、普通に加算でミックスされていた。意外と音って単純なの
ね・・。そういえば波形データ触る時も、単純に波形を足したりとかしてたわ。
なんだか当たり前の事を再確認した。

でも、その足したのをVSTエフェクトで加工したいのだけど、インのあるVST
への音を渡し方とかがさっぱりわからず。これがうまいこといくと、BUSを
作る事ができて、いい感じの音になるんだけどなぁ~。

■というわけで
次の方向性を模索するも、やはり、何もかも全部自分で用意したい!という
ロマンに取り憑かれてしまった。もやもやしていた仕様をまとめると、

・VSTインスト、VSTエフェクトを自作
→GUIを持たないシンプルなFM音源ナド
・VSTホストを自作。ZMS互換のMMLベース。
→データはGUIを使わず、全部テキスト
・音データを自作
・それらが動くレトロ的ゲームの作成

この辺りを狙いたい。狙った所で何があるのか全くわからないが。

2015年6月2日火曜日

Windows:VSTホストを作れるのか?

色々あったけど、途中で書いておけばよかった・・。だいぶ忘れた・・。

さて、FM音源ドライバーが一旦落ち着いて(バグはあるが)、次の展開を考えていた所、
ドライバーの演奏部分がいい感じにできているので、FM音源だけでなく、VSTの
インストゥルメントをプラグイン的に挿して演奏できたら面白く無い?という事に至る。

そこで早速ググってみるも、日本人は実質一人くらいしかVSTホストに関して
取り組んでない感じ。いや、やってるんだけど、ググっても全く出てこない。

この神様のような人の作ったVSTホストを解析して、ウチの演奏先をVSTにできる
のか、ということで2日程試行錯誤。

結果的には、先ほど音が鳴った。すごい。

でもハマった所をいくつかメモ。

■余計なライブラリを使うの止めて!
<balor>
神様もGUI部分は面倒臭かったらしく、2011年くらいに開発が止まったライブラリを
使っていた。balorというGUIなどをちゃちゃちゃと作れるライブラリ。

これに依存しているGUI部分の解析に時間がかかった・・。

DLしてきてそのままリンクしてもビルドできず。そこでプロジェクトを見つけてリビルド
してみるも、ビルドエラーなどで全くライブラリ作れず。神様はちょいちょいと修正
したらビルドできたよ!とか言ってたけど、何か決定的な壁を感じて断念。

GUI無しでも行けるはずなので、そこはもうbalor無しで取り組む事に。

<boost>
これは昔もミンナ使ってたライブラリだなぁとか懐かしい感じに。

確かにboost使うと色々と便利なのでこれ使い出したら頼っちゃうよね・・。
でもリンクやライブラリのコンパイルにえらい時間がかかった・・。四苦八苦。

スタティックとか色々の設定あるけど未だわからず。

<std>
もはやC++では当たり前の存在らしいstdライブラリ。標準ライブラリとして普通に
皆さん使ってますな。std::vectorとかすごくいいよね。これで速ければメモリの
無駄使いにならないし。

でもこれの理解にだいぶ時間がかかった・・。

■balorの置き換え
ちょいちょいと修正してみるも理解してないので進まず。なかなかビルドが通らず。
悩んでググってみると、英語のページでいい所を見つけた。

すっごくシンプルにVSTを読み込むサンプルがあった。

ここのサンプルをちょいちょいと試したら、VSTが読み込めた!やった!

そしてこのサンプルの内容がわかってくると、ようやく神様の作ったソースも
内容が少しづつ理解できるように。

そこで、英語のサンプルからちょっとずつ神様のサンプルへ移行。

■ネームスペース
未だよくわからんけど、コードの書き方に自分ルールが持ち込めるという事
らしいが、これにだいぶハマった・・。まあ自分ルールはいいんだけど、サンプル
としてはもっと素っぴんの状態でお願いしたいよね・・。

■クラス化
C出身で未だにCっぽいプログラムしか書けないが、サンプルを読むのにC++な
クラスは必須。最近は少しづつクラスの書き方も読めるようになってきた。
自分ではなかなかクラス設計できないんだけどね!

2015年2月9日月曜日

andoroidでサウンドを扱うクラスを調べてたら同時発音数わかった

android開発において、サウンドを扱うクラスはいくつかあるらしい。

・MediaPlayerクラス
→連打苦手なので、BGMに合うらしい
・SoundPoolクラス
→長い音は苦手(10秒まで)、SEに合うらしい
・AudioTrackクラス
データをオーディオハードウェアに直接書き込むことができる

という事で、andengineの中身を調べてみたら、
Music→MediaPlayer
Sound→SoundPool
になっていた。うーむ、なるほど。無難。

そして!!調べてたら出てきた!!同時発音数!!!

public static final int MAX_SIMULTANEOUS_STREAMS_DEFAULT = 5;

っていう所が同時発音数だって!!今のとこ5音!!!爆笑!!
5音っていつの時代のゲームだよ・・。
まあ、モバイルのハードだからしょうがないとは言え・・。
せめて倍の10音欲しいよね。

というわけで、andengineのライブラリを書き換えて10音に設定!
org.andengine.audio.sound
SoundManager

本当は16音くらい欲しい!!
でもココ増やすと、1音づつスレッドが立ち上がるみたいで、処理が
すげー重くなるとの事。なんだその仕様・・。実験必要かしら。

まあハードが色々あるからしょうがないのかしらん。

そして、AudioTrackについて考察。

CRIのADX2なんかは自前でAudioTrackを使ってループ処理など
をやってるから、曲途中のループとか、色々と細かく出来ると言うことか・・。

AudioTrackは音関係のアプリを作るには通らないといけない道っぽい
けど、通常はみんなMediaPlayerかSoundPoolに逃げてる・・。

まあ今の問題は同時発音数だから一旦はこれでOKか!

2015年2月6日金曜日

andengineサウンドまわりメモ

andengineで音を出そうと思うとすぐに出る。
SEを出したり、BGMを鳴らしたり。

でも、簡単な事はできるけど、もう少し突っ込んだ事をやろうと思うと、
自分で何かを用意しないとできない。

■今の所できる
・音を出す
・音を止める
・音量の調整
・BGMの最初から最後までのループ

■わからない
・同時発音数→数が知りたい。もしかして機種依存!?
・定位の設定

■今の所できない
・音の優先順位→ちょっと鳴るとすぐに音が切れる
・sceneをまたぐBGM→sceneごとにBGMが鳴る
・Soundオブジェクトを配列で用意する事

今後の事を考えると、音以外にもsceneをまたぐ方法を見つけないと
色々と困るので何か必要。

2015年2月4日水曜日

落ちるコードと落ちないコード

音を付けている時に発見。
現在原因がわからずにそのままにしてるもの。

落ちる
private Sound sTaiko[] = new Sound[2];


落ちない
private Sound sTaiko0,sTaiko1;

以前、沢山のsceneを作成せずに、一つのsceneでやっていた時は、
Soundの配列はうまくいっていた。sceneを沢山作成したとたん、
配列が落ちるようになった・・。うーむ、理由わからず・・。

配列がうまく使えない場合は汎用的なものが作れないよ・・。