キーボードをピアノの鍵盤に見立ててキーを押すと音が鳴る簡単なシンセサイザーをSDLで作った後、音色もいじれるようにしようとQtでGUI化した。
オーディオストリーミング部分を移植中にQt(5.10)で説明してるものがあまり見つからなかったのでここで自分のやり方をまとめておく。
windeployqt.exeでdllをコピーしてきても実行ファイルが動かない
WindowsでQtを勉強し始めて簡単なアプリができたので、とりあえずQt Creatorでreleaseビルドしたあとに生成されたexeファイルを実行しようとした。すると実行に必要なdllが見つからないよと怒られた。
WindowsでQtアプリの配布パッケージを作る(windeployqt.exeを使ってみた) - 理ろぐ
自分で探してくるのも面倒なので何かいいツールがないか探していると、windeployqt.exeというものが既に用意されているのを知った。開発環境はQt5.10.1 & MinGW5.3.0 32bitなのでC:Qt\5.10.1\mingw53_32\binにあったwindeployqt.exeを上のブログのように実行するとdllを自動でコピーしてきてくれた。
これでよし、と思って実行してみると、libwinpthread-1.dllがないよと怒られた。どうもこいつはMinGWやサードパーティのライブラリはコピーしてきてくれないらしいので手動でwindeployqt.exeがあったところからdllをコピーした。
すると、今度は「プロシージャ エントリポイント *** がダイナミック リンク ライブラリ xxx から見つかりませんでした。」(xxxはdllだったりexeだったり)と警告された。不勉強なのでどういうことかと調べてみると、これはどうも間違ったdllをコピーしてきてますよ、ということらしい。
libwinpthread-1.dllと同じところからdllをコピーし直してみたけど、同じエラーが出続けた。C:Qt\Tools\QtCreator\binの方のデータをコピーしてきてもエラーが出続けるので、もう自分で必要なdllを全部コピーしようかと思っていたところ、Stack Overflowで自分と同じことを質問してる人がいた。
Cannot run Qt C++ release build. 'The procedure entry point could not be located' - Stack Overflow
ビルドしたexeファイルをC:Qt\5.10.1\mingw53_32\binに移動させて実行すると、問題なく動いた。こりゃwindeployqt.exeが間違ったdllをコピーしてるのが確実なので、windeployqt.exeで自動コピーしたdllを1つずつC:Qt\5.10.1\mingw53_32\binのものに置き換えていった。するとlibstdc++-6.dllを変えた途端アプリが実行できた。
windeployqt.exeについて調べてみると、いくつかdllが間違ってコピーされることがあるようで、信用しすぎるのは良くなさそうだ。
雑記#8
MAMEのOPNAのモジュールをC++でラッピングして、キーボードを押すとFMとPSGをリアルタイムで再生するプログラムをSDLを使って書いた。
以前使ったときはSDL1.2だったけど、今回はSDL2.0を使った。いくつか変更点があったけど、もともとどうやって使っていたのか忘れていたのでそれほど気にならなかった。
キーボード入力処理と音声処理はスレッドを分けて置いたので、これから作るOPNAトラッカーには音声処理のスレッドをそのまま移植すればいい感じになった。
コーディングするついでにC++11や14、17についても勉強しているので、この1カ月でプログラミング力も鍛えられた。
去年の11月ごろから次の新曲を作る作る詐欺をし続けていたので、今回やっと作曲をすることにした。
自分でトラッカーを作るのに他のトラッカーを色々触って研究するためにも、今回はいつものGoatTrackerでのSIDじゃなくて0CC-FamiTrackerでのファミコン曲を作ることにした。
ファミコンもVRC6とかの拡張音源があるけど、とりあえず標準の方形波x2、三角波、ノイズの4chだけでやってみる。ADPCMはなんとなくやめておく。
ファミコン音源は日本でも人気があるからネットで探しても情報が沢山見つかるし、トラッカーのチュートリアルも日本語で書かれているのでとっつきやすい。
ただ、自分の作曲力は相変わらずなので苦労している。
最近自分が作りたい曲は、昔のゲーム音源で普通の曲を鳴らすイメージなので、「ゲームっぽさ」が強い自分の癖の曲はとても気持ち悪い。
雑記#7
MAMEのYM2608(OPNA)音源部を取り出して鳴らそうとしてる。
前に探したときOPNA系のエミュレーションとしてはfmgenがあったけど、実際PSGの出力波形は0-maxのところが(-max)-maxになっていたのが気になったので別のものを探してみたところ、前に使ったVGMPlayの音源部にMAMEのコードが使われていたので調べてみた。
今GitHubに上がってるMAMEのコードを見てみるとC++で書かれていて、継承が複雑に絡んでいて必要なものだけ取り出すのが大変で心が折れてしまった。
VGMPlayのほうはC++に書き換える前のCで書かれていて、既にVGMPlay用に音源部のみ抜き出した状態で扱いやすく、中身のコードもそれほど変わっている様子がなかったのでそちらを使った。
fmgenは関数の説明がしっかりと書いていたので実装しやすかったが、MAMEのほうは関数がずらずらと書かれているだけだったのでまず音を鳴らすまでが大変だった。
個人的にはMAMEの実際のチップと同じ順序で値を書き込むよりfmgenのように簡単にレジスタ操作できる方がよかったのでCのコードをラッピングする形でクラスを作った。CのコードをC++に直接移植する根性はなかった...
大体はまとまってきたけどまだリズム音源部は試していない。たしかMAMEはfmgenと違ってドラムデータを内部に保持しているはずだったのでそれも確認しておく。
FM音源部とPSG音源部の音量比をどうするか悩んだが、そもそも実際のチップがミキシングを外部で行なっているので音源ボードによって音量比が違っているし、どれが基準と決められないのでとりあえずそのままにしておいた。
MAME内部で波形サンプルを出力した時、サンプリングレートはチップのクロック数から算出される形式なので44.1kHzとは限らず、さらにFM音源部とPSG音源部でレートが違っているのでサンプリングレート変換する必要がある。
サンプリングレート変換については何も知らなかったので色々サイトを巡って調べた。
VGMPlayでは線形補間しているけど、調べてみるとこの方法では結構誤差が出るみたいなのでsinc補間というものを使おうと思う。
雑記#5
OPNAのPSGでSID voice&Buzzer Effectをやってみたい。
チップチューンのすべてを読んでいたら、Atari STでの話でPSGで三角波、ノコギリ波、PWMを鳴らすことができるのが面白そうと思ったので調べてみた。
Tao - Birth (Atari ST Magic Synth 2.5.2 music)
これまでイメージしてたPSGの曲(日本の昔のMSXのゲームとか)とだいぶ違っていたのでPSGでもここまでやれるのかと驚いた。
このYM2149はOPNAのPSG部分をほとんどそのまま分けたものと聞いていたので、OPNAでもできるはずと最近は色々情報を調べてる。
自分はハードウェアのことは全くダメなので、ソフトウェアでOPNAを再現するfmgenを使うことにした。ただ、どこまで実物の挙動を再現しているのかはよくわからない。波形をいじるのに割り込みなども使っているみたいなので、そのあたりのプログラミングをするのもなかなか大変そうだ。
情報を調べるのに英語力が必要でかなり苦労してる。やっぱり英語を勉強しないとダメだな。
やっと最近、なんとなくだけどSID voice(PWM)とBuzz effect(三角波など発声)のやり方が分かってきたのでちょっとずつ試してみたい。
いろいろ調べてるついでに、PSGでSIDっぽいこともできないかなと、ドラムの再現をしてみた。
ドラムとイメージしてパッと出てきたのがファミコンのBucky O'Hareだったのでこの曲でテスト。
普通にノイズやパルス波を鳴らすだけじゃなくて、カウント単位で切り替えたりするトラッカーで作るみたいにすると、いい感じにバシバシするドラムができた。
その反面、カウント単位で指定しているので全体の音長指定をするときに途中でカットするマクロを別に作らないといけないのがなかなか大変。
主旋律、ベース、ドラムで3ch使っているけど、頑張ってベースとドラムを同じチャンネルに纏めたら2ch目にコーラスを入れたりして聞こえが良くなりそう。でもMMLでやるとかなり労力を使いそうだ。
やっぱりトラッカーが欲しい。