2012年3月14日水曜日

デューティー比は落とす

ここ数日、独自PSG音源エミュレータを作成する方向で作業をしていましたが、ちょっと転機。

当初、波形は「三角波」、「ノコギリ波」、「短形波」の3種類で、デューティー比を弄れる感じにしようと思ったのですが、基本周波数が22050Hzだとあまり綺麗な音が鳴らなかったので、デューティー比は5:5固定にします。

そうなると、独自PSG音源は、PSG音源ではなく、独自の波形メモリ音源になるのかな?
少なくとも、波形に関してはプログラマブルではなく、完全固定になるので。
そもそも、私は「PSG音源」の厳密な定義はよく分かっていませんが。
「プログラムで弄り易い音源」という意味なら、波形メモリ音源もPSGの一種のような気もする。

ちなみに、デューティー比というのは、波形の正負値の比率のことです。

例:デューティー比5:5の正弦波

で、この比率を変えると、音色が「かなり」変化します。
波形エディタで書いて鳴らしてみると、楽しいかもしれません。
波形エディタは、下記URLにある「効果音エディタ_D」というのがオススメ。
http://www.geocities.jp/hirogamesoft/se_d/se_d.html



デューティー比が弄れれば、波形パターン(音色数)が少なくても、色々な音色が作れます...
なので、性能のためとはいえ、ちょっと残念かも。
遅くとも600MHz程度の超高速なCPUを積んでいるAndroid端末なら、全然気にならないレベルなんですが、CPU占有が多すぎると消費電力量が多くなってしまうので、やはり、性能を一番気にしておきたいところ。

2012年3月13日火曜日

合成完成

前の記事に書いたとおりのアルゴリズムで、音符の合成ロジックを作ってみたところ、アッサリと合成処理が完成。

プログラムを書くのより、サンプルの演奏データを作る方が時間が掛かったかも。
とりあえず、↓こんな感じ。
http://www.k2.dion.ne.jp/~ysuzuki/seikou4.mp3

ようやく、音楽らしい音楽を鳴らせるところまできました。
あとは、MMLで色々と細かいけど重要な機能を色々追加すれば、音源機能はとりあえず完成かな。
当初、ノイズ音源も作ろうとしましたが、ノイズ(ドラム)はPCMの固定波形パターンを鳴らせば良いんじゃないかと、思い始めました。(その方が、処理が軽いので)

いっぺんにやろうとするから難しい

独自PSG音源専用のMMLコンパイラで、とりあえず、1チャネルで音楽を鳴らすことに成功。
毎日だいたい夜11:00頃帰宅(これでも早いほう)なので、ウィークデーの進捗はこの程度。
次の課題は「複数チャネルの音をどうやって同時に鳴らすか」。

まぁ、その辺は簡単に計算できます。
今のところ、PSG音源に対する指示情報としては、以下の7種類。

  1. エンベロープ1を設定(キーオンしてから100%になるまでの周波数)
  2. エンベロープ2を設定(オーオフしてから消音になるまでの周波数)
  3. チャネル別のボリュームを設定
  4. マスターボリュームを設定
  5. キーオン(音を鳴らす指示)※音色や音程も一緒に指定する仕様
  6. キーオフ(音を止める指示)
  7. 待機

網掛けしている待機という指示情報だけに着眼すれば良いだけです。

仮に、
  • Ch.1: event1 → wait(100Hz) → event2
  • Ch.2: event3 → wait(50Hz) → event4 → wait(75Hz) → event5
という感じで並んでいたら、

event1 → event3 → wait(50Hz) → event4 → wait(50hz) → event2 → wait(25Hz) → event5

という感じにすればOK。

アルゴリズム的に表現すれば、

  1. 待機時間が短い方の待機時間を採用し、
  2. 長い方(非採用)の待機時間は、採用値を減算
  3. 次の待機時間についても同じ処理で求める

で、OKな筈。(未検証)

処理としては単純。
問題は6チャネルの場合、フラグが沢山有り過ぎて、アルゴリズムが無茶苦茶複雑になりそうだ・・・
と、思っていたのですが、ピンポン録音の要領で、

  1. チャネル1+チャネル2=チャネルA
  2. チャネルA+チャネル3=チャネルB
  3. チャネルB+チャネル4=チャネルC
  4. チャネルC+チャネル5=チャネルD
  5. チャネルD+チャネル6=チャネルE

って、やれば良いだけですね。
物凄く簡単だった。

これなら、明日にはチャネル合成ができるかな。(本業の状況次第ですが)

ちなみに、チャネル毎の音の合成(音源レベルの話)をどうやるのか疑問だったのですが、これは単純な足し算でOKでした。音の合成ってこんな簡単だったのか。(てっきり、もっと複雑な「xxxの公式」みたいなヤツでも要るのかと)

2012年3月11日日曜日

構文解析まではできた

独自PSG音源エミュレータで音楽を鳴らすためのMMLコンパイラを作成中。
本当は、この土日で完成させる予定でしたが、昨日、スマートフォンを買ったり、色々と設定やらをしたり、遊んでいたところ、完成しなかった・・・orz

とりあえず、今日の昼から開発を再開して、構文解析まではほぼ完成。
ただ、色々と細かい所ができてないです。

構文仕様としては、下図のような感じになりました。(色々足りないかも)

ごく簡単なマクロ言語です。
「$なにがし」でマクロを定義して、「Ch0~5」でチャネル毎の音符情報を書きます。

分解性能を周波数と同値にしたお陰で、「%」というオペランドを使って、音の長さに対するキーオンの時間の割合というものを定義できました(これがやりたかった)。%を低めに設定すればスタッカートみたいな感じになり、高めに設定すればレガートになる感じです。

ちなみに、ボリューム(音量)としては、マスターボリューム(全チャネル共通のボリューム)とチャネル別のボリュームのみで、ヴェロシティ(音符単位のボリューム)は無い仕様にしました。
できなくもないけど、私が作る曲では概ね要りません。
必要な時は、MIDIからの変換ツールの方でボリュームオペランド(v)で調整すれば良いし。
ただ、それだとデータ量が多くなってしまうので、改善の余地ありかもしれませんが、今のところ、多彩なヴェロシティの曲を作るつもりは無いというのが一番の理由。)
一応、データ的にはヴェロシティーに対応させる空き領域は有りますが。

ヒープ破壊のチェック方法@Windows

大方のAndroidプログラマの方には無縁だと思いますが、私が作るアプリの場合、コードの9割強がC/C++で作られているので、ヒープ破壊のバグが発生すると、必然的にデバッグが極めて困難になります。
勿論、ダンプが取れれば、壊れた形跡から概ね何処で壊したか特定できますが。
ヒープ破壊の厄介なところは、壊れ方によっては、何の問題も無く動いてしまうところ。
(スタック破壊なら、/RTCsオプションとかでチェックできますが)

Linuxであればvalgrindを使えば、ヒープ破壊のチェックができますが。
しかし、WindowsのC(VisualC)でAndroid用のソフトを開発している私の場合、それは無理。

RationalのPurifyを使えば、チェックできますが、色々と設定が面倒くさい。
インストゥルメントしてしまうと、動きも重くなってしまうし、モノによっては正常に動かなくなります。
ついでに、結構値段が高いPurifyを個人で買うのはちょっと・・・

Windowsで、お金を掛けずにヒープ破壊のチェックをしたければ、Debugging Tools for Windowsの付属ツール(gflags)を使い、未確保の領域を触った時点でクラッシュさせてあげれば良いです。

gflags -p /full /enable 実行ファイル名

という感じでやってから実行ファイルを実行すれば、未確保の領域を触ったときに落ちてくれます。
あと、実行ファイルをコンパイルする際に/Ziオプションを付与してデバッグ情報をオブジェクトモジュールに設定し、リンク時に/DEBUGオプション+/PDBオプションでPDBを作ってあげれば、コールスタックから落ちた位置を簡単に特定できます。

Debugging Tools for Windowsは、Microsoftからタダで落とせます。
かなり便利なツールの宝庫なので、色々と使ってみると楽しいですよ。
ドキュメントは全部英語なので、読むのが面倒くさいですが。


追記: ちなみにゲームの場合、ヒープは起動時に全部確保して、停止時に全部開放します。
動作中は動的メモリを一切確保せず、リングバッファのみで情報を管理するのが普通。
実は、ヒープの確保は結構重いので、仮に大した量でなくてもそうすることが、ゲーム作りでは常識。
ちなみに、私にはもう関係無いことですが、Javaの場合、アプリはJヒープ(JavaHeap)という領域を使いますが、これはもっと重い。
多分、Javaを開発した当初は、エクスプリシット(参照カウンタが全部外れれば解放する)で作っていたと思うのですが、Jヒープの余りの重さに悩んだSunの技術者が、「ヒマな時に解放すればよいんでない?」程度の浅はかな考えで、GCなる処理を作ったんだろうと思います。(私はSunの人間ではないので単なる勘ですが)
Javaでゲームを作っている人は大変だろうなぁ・・・と、思います。

2012年3月10日土曜日

広報活動(INVADER BLOCK2)

INVADER BLOCK2の広報活動として、フリーゲーム夢現さんにWindows版の記事を投稿。
フリーゲーム夢現さんは、リンクの少なさに定評がある私のホームページ(http://hp.vector.co.jp/authors/VA040196/)のリンクに載せているゲームレビューサイトです。
「リンクが少ない」っていうより、現状、フリーゲーム夢現さんしか載せてませんが。

フリーゲーム夢現さんは、去年SHOT03を販売した時にも利用させていただきました。
SHOT03は、今になって思えば、フリーで出しておけばそこそこ遊んで貰えたかも。
それでも、300本ぐらいはダウンロードされたので、「フリーじゃないから売れなかった」のではなく、純粋にツマらなかったのであろう・・・と、反省しておきます。(フリーだとそもそも売れませんが)

幸い、INVADER BLOCK2は現時点で数本、売れました。
ご購入いただいた方々は本当にありがとうございます。
正直な所、「1本も売れないんじゃないか」と思っていたので、最初の1本が売れた時は驚きました。

ちなみに、INVADER BLOCK2が売れ始めたのは、VectorでWindows版を無償公開後。
Windows版を無償で公開するというやり方は、中々良かったかもしれません。
それをやるのは、技術的に少し大変かもしれませんが。
(エミュレータを作れる程度の技術力があれば、簡単に作れます)

なるほど

スマホといえど、携帯の延長線上のものだろ・・・と思ってナメていたいのですが、確かに便利。
携帯と違い、5,000円/月払ってもまぁ良いかな・・・と、思える代物でした。
在宅時はWiFiをonにすれば、動画もサクサク見れる。
動画を再生すると、電池の減り方が大分アレですが。

入力系統はどうあがいてもWindowsには敵わないので、開発や文書を書く作業には向きません。
しかし、エンターテインメント的な要素で使う分には、PCよりも洗練されているという印象。

ただ、PCの方は、Windows8でひと波乱有りそうな気がしますが。
仕事道具としては、iOS/Androidなんかより断然、Windowsの方が使い易かったのに・・・
まだ、評価版を会社で触ってみただけなので、製品版ではどうなるか分かりませんが。

私見ですが、Windowsはタブレットなんかに載せず、PC専用のOSとしてシェアを保つのが最善の選択肢だと思っています。
しかし、Windows8は単なるiOS/Androidの劣化版・・・というのが正直な印象。
元々、Windows自体がMacをパクッて作ったものなので、今に始まったことではないですが。
そして、昔はそれで上手くいったので、Microsoftが8でコケるか否かは未知数か。

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...