
S.F.@SFPGMR
Reaperのjsfxの理解をさらに進めるために、emu2149.cをEEL2に移植してみることにした。 https://t.co/EnNNxvALyg

まだまだコードはハリボテもいいところだが😅
ベースとなるコードはこのCソースである。
私にとってはものすごくわかりやすいので。
このコードはYM2149/AY-3-8910のチップのエミュレータである。
GitHub - digital-sound-antiques/emu2149: A YM2149 (aka PSG) emulator written in C.
A YM2149 (aka PSG) emulator written in C. Contribute to digital-sound-antiques/emu2149 development by creating an account on GitHub.
これ作れば音源としてREAPERで使える。30年以上前にX1Cという8bitPCのPlay文+αでRYDEENをカバーしていてたりしてて、ちょっとReaperで再現してみたくなったので。
ソフトウェアエンベロープとか、2CH使ってピッチをずらしたりしてコーラスのような効果を出したりとか、リズムだけキーボードで音が鳴るようにして重ね録りしたりとか。今だともうちょっと洗練した感じでできるんじゃないかなと思ったものでね・・
昔はほんと何も知らなくて、出力波形の違いで音色が異なるなんてこともわかってなかったね。なんでPSGはシンセみたいな音がでないんだ・・って悩んでた時期もあったな、そういえば。
しかしこのEEL2っていう言語は面白いなあ。まず驚いたのはいわゆる配列ってのがないってことなんだな。一応各括弧でインデックスアクセスする記法はあるんだけど、これは配列ではなくてメモリアクセスに近い。
a=10;
a[100]=1;
は10+100番目のメモリに1をセットするっていう意味になるんだな。
要するにaに入れた10はメモリの先頭番地になり、それにさらにオフセットしてアクセスするために角括弧が存在してるってことなんですわ。そして数値としてメモリに保存される型はdoubleしかないんですな。つまりオフセットはdouble単位になるってことですわ。
でメモリってのが既に確保されていて、自由にアクセスできるようになっている。実際のところどれくらいのメモリが初期に確保されているかは今のところよくわからない。
最初悩んだのが初期値ありの配列ってどう扱えばいいんだろうなってことだった。
例えばJSなんかだと
const a = [0,1,2];
みたいなものはどう書けばいいのかってことが最初わからなかった。
答えとしては
offset = 0;
mem_set_values(offset,0,1,2);
こう書けばいいみたい。なんと原始的なと思ったがどうなんだろうな。原始的なのか、革新的なのか・・
これだとJSの例と対比できんか。
a = 0;
mem_set_values(a,0,1,2);
こうですわな。これで
c = a[1];
ってやるとcに1が入るってことですわ。
あとNamespace Pseudo-Objectsってのもなかなかの驚きですわな。
No ImageREAPER | JSFX Programming Reference - User Functions and Namespace Pseudo-Objects
こういう記法の言語ってほかにもあるのかもだけど、面白いなあって思ったな。
メモリは「初期化時にすでにある」って感じなんで、先頭のオフセットから順番にデータ配置を考えながら変数を定義していく感じになるんですな。
今日は変数とボリュームやピッチのデータを定義して終わりって感じですな。 https://t.co/c2Lqq7YZY5

実際にPSGというチップの動作をまねるっていうよりはオシレータやEG、ピッチの癖をまねるって感じで、レジスタでピッチやEGのマスクをセットするとか、そこまではまねないつもりなんだけどね。それと発音数は可変にするつもりだしね。
ノイズ出しながら、ピッチを上げ下げする音をミックスするとシモンズみたいな音が出るんだよね。
今聞くと全然違うのかもしれないけどね。
数値がdouble一択ってのも面白いよなあ・・シフト演算子とかはいったん整数に変換されて実行され、また戻るみたいだけどね。でもこの動きはスクリプト言語はまあ普通かもね。オーディオだと32bit floatで処理ってのがまあ普通なんで、doubleあれば精度的にも十分なのかなあって気もするね。
なので整数演算は型変換のコストがかかるんでおそらく遅くなっちゃうんだろうな。
ひととおりコードの移植が終わり、あとはMIDI受信からピッチに変換したりだとか、ポリフォニックの制御コードを追加して鳴らしてみようと思う。
『AY-3-8910のバグ挙動』を利用した『疑似三角波』ですが、海外のチップチューンでは活用しまくりですね。どういったものかというと『エンペローブ波形』と『Mトリガーのバグ』を利用しています。本来はMトリガーを引くと『ぽ~ん』と鳴るだけなのですが、実はその減衰後にも音が出るバグがあります。 https://t.co/WGQaCComOv

今ちょっとものすごく初歩的なことに悩んでいて・・
PSGのEGのトリガーって何で発動するのかな?っていうことなんだけどね・・いろいろ調べてるんだけどよくわからんなあ・・って感じ。かつてそこそこいじってたチップなのに・・
で先ほどのPSGで三角波・鋸波をだす方法に行き着いたんだけど、そこではボリュームのMビットをONにするとトリガーになるみたいなんですが、EMU2149やmameのay8910のソース見てもそれらしき挙動を示すコードが見つけられなくて😭
しかしかつてBASICでPSGをいじっていたときは、EGを有効にするには、SOUND命令使ってレジスタいじくってたような記憶もあるんだよね。完全に忘れたなあ・・
ここみるとMMLのM/S命令でエンベロープと周期が指定できるみたいですな。そうだったかあ・・
参考資料:MSX BASICのMMLの仕様 | Electronic Information Research Laboratory
出典:「MSX2 パーソナルコンピュータBASIC説明書」(昭和60年11月、編集:株式会社アスキー、発行:松下電器産業株式会社 情報機器部)例と、PSG for Webで対応していない部分は省略しています。音の高さA〜GCDEFGがハ長調
私のPSGのいじくり全盛期はX1/C所有時代なので、その当時のHu-BASICのMMLがどんなだったかなあ・・
あれほどいじってたのに思い出せん・・
しかしPSGも奥が深いんだなあ・・
私の知識なんてかなり浅いわ・・
X1 Turboのマニュアルだと、やはりSOUND命令とPLAY文のVを16にして演奏してるな。なんとなくこうだったような気がするな・・
やっぱりMとかSとかそういう高級な命令はなかったよなあ・・MSX-BASICすごいな。 https://t.co/Oq2xiKTx0u

emu2149.cを読むに、EGのカウンタがリセットされるのはEGの周期指定か、EGのパターンを指定するときのみっぽいんだな・・だとすると、発音のたびにEG周期/パターンを指定しないと、ワンショットなパターン(例えば0とか)だとうまく鳴らんような気もするんですな。 https://t.co/07IXe4wht2

しかしそれを各CHで行うと、EGは共通だからそのたびにリセットがかかり、他のCHの音量に影響を与えそうだけど、そういう仕様だったか思い出せんなあ・・
各CHでEGのカウンタを持ってるわけではないもんな。やっぱりそういう仕様なんだよな。時代の流れはこのEGを使うよりも、ソフトウェアEGで音量をコントロールする方向に行ったもんな・・
ここはあんまりこだわる必要はないのかもな。
しかし思い出せんのが悔しいところ😰
mameのay8910のコード読んでて分かったのですが、8930ってのはEGがCHごとに設定できるようになってるみたいですな・・
やはり8910はCH共通のEG/カウンタだってことですな・・ https://t.co/o5FGualI34

昨日から続きを作り始め、ようやく音が鳴りはじめた。やっぱりソフトウェアによるEGとLFOは必要ですな。。ライブラリがあるんで実装は簡単に出来そうだが、ReaScriptまわりも勉強しながらなのでなかなか進まない感じ。
まだ途中だが、鳴らしてみたものをアップ。
youtu.be/-KZT4welJs4
PSGの同時発音数がもっとあればなあ・・っていう30年以上前の夢は叶った感じもするね。純然たるPSGではないけどね😅
ちょっと仕様を変え、1音にPSGチップ1個相当を割り当てて、8音ポリで鳴るようにしようと思う。
なので3音×8だから24音同時に鳴るってことですわな。PSG1個を1つの音色つくりに使う贅沢な仕様😅ってことですな。
ピッチを微妙にずらして重ねてコーラスがかかったような効果を実現したりとかしたくなったんだな。DAW上でエフェクトかけれるんでコーラスかければいい話なのだが😅
実際こんな数のPSGを同時に鳴らすってことは物理的にやろうとするとかなり面倒なことだと思うんだよね。まさにソフトウェアや現代のPCの力を実感しますな。
PSG風もどき音源の改造がとりあえずできたので鳴らしてみた。やっぱり単音よりは音をピッチずらして重ねたりユニゾンで鳴らしたりできるんで音作りの幅は広がるよなあ・・
youtu.be/-OAgy3KXxXM
ピッチに関してはPSGの仕様に合わせてあるんで、高音になると若干音痴になるところもそれっぽくなってると思うんですがね・・
しかしまあ、1トラックあたり1つの音源を割り当てるとして、3音×8ポリなので24音となり、今回のデモ曲では5トラック使っているので最大で120音鳴るってことになるんですわな。なんとPSG40個を使ってる勘定になるのですわ。まあなんと贅沢な・・
ノイズ・ジェネレータも動いてるんで、ソフトEGを実装したら何かデモ曲でも作ろうと思うんですけどね。
あ、LFOもか。
PSGは音量も15段階しかないので、内部的には丸める処理を行っている。なので音量も滑らかではなくてカクカク変化する。
ナムコの「ニューラリーX」のBGMを演奏してみた。譜面は「ALL ABOUT NAMCO」を使用した。PSG+BASICのPLAY文でこの「ALL ABOUT NAMCO」の譜面を打ち込んで毎日飽きもせず遊んでいた頃を思い出しましたわ😊
youtu.be/Wci6xSLPd2A
しかし私は「ラリーX」は苦手でもっぱら友達がプレイしているのを対面で見ながらBGMを楽しんでいたクチであった・・
ソフトウェアEGができたので演奏してみた。
ちょっとプチプチするなあ・・
youtu.be/ajRyHZ04GG0
PSGが一般的だったころは3音以内での曲アレンジとなって、それが特徴をよりいっそう際立たせてたんですよね。高速アルペジオとかね。でもいっぱい音が使えるとまたそれはそれでいい感じ。ノイズ使ってリズムとか鳴らしてみたいね。
このMSX2のがんばれゴエモンのBGMのアレンジが秀逸だと思うんだよね。SCCなしのPSGだけのアレンジなのかどうかわからんけどね。このゲームもかなりハマッたはずなんだけど、内容に関して記憶がまったくない😭
youtu.be/No56PGZyRNQ
伸びる音にビブラートかけたりしててよくできてるなあって思うんだよな・・
そういうわけでピッチEGとLFOの実装ができたので動画をアップ。スネアの音にピッチEGで音を下げながら鳴らすとええ感じになるってのはX1所有時代に発見したテクニックですわ・・
youtu.be/kE1wePKovm8
しかしJSFXっちゅうのはなかなかのパフォーマンスで動作するなあ・・
このEEL2っていう言語はそもそもの起源はWinAmpというオーディオプレイヤーを作っていたNullSoftというベンダが開発したEELをベースにしているみたいですな。
そもそもReaper DAWを作っているCokcosはWinAmpを作ったJustin Frankelさんが作った会社なのか・・
ああ、それでEEL2なのかあ・・