#5 GEN日記FM音源DACテーブル追加。(2006-01/21)
■DACテーブル追加。(2006-01/21) 昨日もDGENの「FM.C」だけ弄ってた。 (注:このDGENは1.00です。最新のDGENはもっとずっと進んでいます。 スキルがあり、開発をしたい方は開発者に直接コンタクトをとって下さい。 私は開発者とは全く関係のない第三者です。 あくまでこのページの話は実験用途(教育用)です。)
二日前とまったく同じテスト。(「バーニングフォース、サウンドテスト03」このカートリッジは、 PCMを全く使用していなく、BGM==YM2612、効果音==76496に分離しているので、 サウンドチェックに使用しています。またラスターパレットのチェックも出来ます) 二日前(元)
OFF | 79fps |
11025kHz | 69fps |
22050kHz | 65~66fps |
44100kHz | 56~58fps |
OFF | 79~80fps |
補間付5512kHz | 72~73fps |
補間付11025kHz | 70fps |
22050kHz | 65~66fps |
44100kHz | 60~61fps |
5512kHzは補間がなければ、とても聞けた音質ではない。 補完は、「昔の携帯電話」や「しゃべるおもちゃ」や「PSG」や「ファミコンっぽい」音質。 長時間聴くと耳疲れする。 また、DACが入ると、単純線形補完では、補完との相性が悪く、 バリバリノイズが発生する問題もある。(例えば「OutRun2019」)
■補間は4倍補完で、ソースは、 { int r1,r2,r3, l1,l2,l3; ADVANCE_PAN switch(F2612_ddd){ case 2: case 3: /* t1 rt lt t2 r1 l1 t3 r2 l2(2nd[rt_old lt_old]) t4 R3 L3(2nd[r3 l3 ]) t5 r3 l3( rt_old lt_old ) */ r3=rt_old; l3=lt_old; lt_old+=lt; lt_old>>=1; rt_old+=rt; rt_old>>=1; r2=rt_old; l2=lt_old; l1=l2; l1+=lt; l1>>=1; r1=r2; r1+=rt; r1>>=1; r3+=r2; r3>>=1; l3+=l2; l3>>=1; /* for next */ lt_old=lt; rt_old=rt; break; } // rt |= (lt << 16) ; // //*((unsigned long*)bufR) = ((lt & 0x0000FFFF) << 16) | (rt & 0x0000FFFF) ; // *((unsigned long*)bufR) = ((rt & 0x0000FFFF) << 16) | (lt & 0x0000FFFF) ; // bufR += 2 ; switch(F2612_ddd){ case 0: *((unsigned short*)bufR++) = rt; *((unsigned short*)bufR++) = lt; break; case 1: *((unsigned short*)bufR++) = rt; *((unsigned short*)bufR++) = lt; *((unsigned short*)bufR++) = rt; *((unsigned short*)bufR++) = lt; break; case 2: *((unsigned short*)bufR++) = rt; *((unsigned short*)bufR++) = lt; *((unsigned short*)bufR++) = r1; *((unsigned short*)bufR++) = l1; *((unsigned short*)bufR++) = r2; *((unsigned short*)bufR++) = l2; *((unsigned short*)bufR++) = r3; *((unsigned short*)bufR++) = l3;
の辺、YM2612UpdateOneがいくつもあるのは判りにくいので、はじめは defineにしていたんだが、タコなソースでも一つに纏めたほうが、 パフォーマンスアップするようだ。 ちなみに、switch(F2612_ddd){の case 0:は44.100kHz case 1:は22.050kHz case 2:は11.025kHz
RISCチップでキャッシュが重要なんだから、キャッシュフローする可能性のある ループ展開等避けた方が無難だ。YM2612UpdateOneがいくつもあるのはこれに 近い状態で、避けた方がパフォーマンスアップする。もし、MAME辺りを移植するのなら、 グラフィック関連の大量のdefine(半透明モードとか拡大、回転、OBJとかBGとか)も 展開しないで、ある程度直書きした方が、いいかもしれない。
BufRの辺は、構造上多分バグがある。気がついているものの。 他を直す予定との兼ね合いで放置。どうせ聞いても判らないし、そもそも余計な心配で、 これでいいのかも知れない。いづれにしても、変更する。 (管理人、間接読み書き方式の**bufferが嫌いなもんで、 unsigned short *bufferRLの直接読み書き方式にする。)
■パフォーマンスアップしたほかの部分は、パン関係。 前略 #define PAN_L 0x80 #define PAN_R 0x40 static int pan0L,pan1L,pan2L,pan3L,pan4L,pan5L; static int pan0R,pan1R,pan2R,pan3R,pan4R,pan5R; 中略 static void reset_channels( FM_ST *ST , FM_CH *CH , int num ) { 略 pan0L=PAN_L; pan0R=PAN_R; pan1L=PAN_L; pan1R=PAN_R; pan2L=PAN_L; pan2R=PAN_R; pan3L=PAN_L; pan3R=PAN_R; pan4L=PAN_L; pan4R=PAN_R; pan5L=PAN_L; pan5R=PAN_R; 略 case 1: /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2610B/YM2610/YM2608) */ 略 /* PAN : b7 = L, b6 = R */ // F2612_PAN[c] = (v & (PAN_L|PAN_R)); switch(c){ /* YM2612 pan swapped? */ case 0: pan0L=(v)&PAN_L; pan0R=(v)&PAN_R; break; case 1: pan1L=(v)&PAN_L; pan1R=(v)&PAN_R; break; case 2: pan2L=(v)&PAN_L; pan2R=(v)&PAN_R; break; case 3: pan3L=(v)&PAN_L; pan3R=(v)&PAN_R; break; case 4: pan4L=(v)&PAN_L; pan4R=(v)&PAN_R; break; case 5: pan5L=(v)&PAN_L; pan5R=(v)&PAN_R; break; 略 #define ADVANCE_PAN \ int lt,rt;\ lt = 0 ;\ if( pan0L ){ lt = out_fm[0] ; }\ if( pan1L ){ lt += out_fm[1] ; }\ if( pan2L ){ lt += out_fm[2] ; }\ if( pan3L ){ lt += out_fm[3] ; }\ if( pan4L ){ lt += out_fm[4] ; }\ if( pan5L ){ lt += out_fm[5] ; }\ lt += bufR[0] ; \ \ rt = 0 ;\ if( pan0R ){ rt = out_fm[0] ; }\ if( pan1R ){ rt += out_fm[1] ; }\ if( pan2R ){ rt += out_fm[2] ; }\ if( pan3R ){ rt += out_fm[3] ; }\ if( pan4R ){ rt += out_fm[4] ; }\ if( pan5R ){ rt += out_fm[5] ; }\ rt += bufR[1] ;\
ってこんな感じ。少し気がついたかも知れないが、 RISCチップなのでレジスタは大量にある。 レジスタ割り付けに誘導する様に書いた方が 速そう(あくまで気分です)。
■YM2612用DACテーブル 管理人、多分耳がいい。現代では耳がいい事のデメリットは数知れずあるが、 メリットは殆どない。あんまりうるさいから、耳の掃除をあまりしない方だ。 その方が幸せに近くなれる。 で、聴感で仕上げたDACテーブル。 「聴感?」うさんくさい。「もっと技術的な話はないのかコラ!」と怒るのなら、 専用のプログラム組んで実機でオシロで測定して下さい。 たぶん、そんなには違わないから。 しっかり数字にしてある。近似関数は適当にでっち上げればよろし。 さとうたつゆき様直伝の最新のMAMEのソースも、 この部分は勝手にリニアーにしてるが、 本当はリニアーじゃないんだよ。って話。 このDACをテストするには、「OutRun2019」がいいと思う。 ゲームを読み込めば、ほっぽらかしておいても鳴るのがポイント高い。 ドラムがこのDACを利用して鳴っている。 ソース取得したい場合。「表示→ソース」を使うと良い。
static int dac2612[256]={ /* it was fuzzy ( serious table was unkown now ) */ -127,-127,-126,-125,-125,-124,-123,-123,-122,-121,-121,-120,-120,-119,-119,-118, -118,-117,-117,-117,-116,-116,-115,-115,-114,-114,-113,-113,-113,-112,-112,-111, -111,-111,-110,-110,-109,-109,-109,-108,-108,-107,-107,-107,-106,-106,-105,-105, -104,-104,-103,-103,-102,-102,-101,-101,-100,-100, -99, -99, -98, -98, -97, -97, -96, -95, -95, -94, -93, -93, -92, -91, -91, -90, -89, -89, -88, -87, -87, -86, -85, -85, -84, -83, -83, -82, -81, -81, -80, -79, -79, -78, -77, -76, -75, -74, -72, -71, -70, -69, -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -55, -54, -53, -52, -50, -48, -46, -44, -42, -38, -32, -30, -25, -20, -10, 0, 0, 10, 20, 25, 30, 32, 38, 42, 44, 46, 48, 50, 52, 53, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 79, 80, 81, 81, 82, 83, 83, 84, 85, 85, 86, 87, 87, 88, 89, 89, 90, 91, 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 107, 108, 108, 109, 109, 109, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 123, 123, 124, 125, 125, 126, 127, 127 };
説明書(説明だから大げさにしてある) /* About 2612DAC: YM2612 ch#6 DAC was not liner., I think it is ... + Amplify : A : 127 + __------~~ / : | _ --~~ / : | _-~ / : | /~ / : | /2612DAC / : | / / : | / / : 63 + / / : | / / linear dac : | / / (of couse logscalable at voltage) : | / / : | / / : | / / : | / / : - || / : |/ : --+----------------+-------------|-> data : 0| 63 127 : 0x80 - <-- 0xff --> + (minus as same it., but zero(0x80 or 0x7f) cross point at linear.) */
追記:2006-01/28日。 流石に「聴感」は非科学っていうか非技術的なので、 今度うちで「メガドラ」実機大改造して、ちゃんと綺麗な音取り出せるようにして、 (耳に聞こえる音を出す必要はない) できればDACデーターが取れれば理想なんだけど、 光変換してPC用のサウンドボードにつなぐだけだもんね。 でも、多分わかんないから、アナログ入力で、 そうだな「PS2」(ファンタシースターⅡ)とか、不自然にDACが大きな音出すソフトで、 録音してチェックしてみますよ。でも、S/N比が高いと、 結局テーブルの下の方のデーター判明しないと思うよ。 それにアナログだから、何よりも歪に注意しなくちゃなんないし、下手なアンプは入れられない。 (位相補正の話。) (人間の耳は位相は鈍感だからオーディオ関係の石は、勝手に位相変えちゃうんだよ。 信号レベルでどうこうしようと思ったらフィルターは使えないし、えらい大変なんだわ。 いわゆるオーディオの回路はつかえないと思って差し支えない。 増幅をするのなら相当神経使わないと、録音結果に意味が無くなる。だからSN比が嫌でも厳しくなる筈。 要するに、オーディオ回路じゃあなくて測定回路を付けようって言ってるの。私ができる範囲でだけどね。)
録音とエミュのDACパートのデータ比較してみよって話。 でもYMの構造上、ローパスフィルターがかかることがDACの必要条件みたいだしなあ。 どおなるかわからん。DACたけ発音してるソフト探せばあると思うよ。 サウンドテストとか丁寧に探す必要があるが、そしたらS/N比があげられるんすけど。 そういえば、ナムコのボールジャックスとか起動音、DACのみじゃあないのかなぁ。確か。 今度調べてみよ。
そおいえば、CDを(無改造)プレステで再生して、プレステのアナログ出力を、 わたしが改造したPC用のサウンドボードでアナログ入力して録音し、 元のCDのデーターとバイナリがどれくらい一致するかチェックしたことがある。 そんなの全然駄目だろと思ったが、やってみたら意外な精度で一致する。 少なくとも間に変な位相補正のアンプは入ってないか、 位相がきれいにずれてまた元に近い状態までずれるらしい。 (フィルターとか通ってる筈だもん。それかプレステのフィルターは下は緩いのか?) これをSN比と歪がどれくらい出るか補正してやって、必要なら出力をまたCDに焼いて再生すれば良い。 何度もやれば、極端に歪むだろ当然。丁度、上の関数のように。そしたら指数で割ればいいじゃん。って話。 そうすれば、特性が出るから、後で補正するって事。この録音システム自体の特性を測定をせな。 基準がないから、信頼性がないだろ。って話。
これがもしうまくいくのなら、後はプレステとメガドラ直結して、アナログ入力で取ればよろし。 でもそんな七めんどくさい事はしたくない。デジタル入力直結がいいなあ。OPNとかなら、 DACが別になってたから、なんとでもなるけど、2612は多分内蔵でしょ?アナログだったらきついなあ。