2016年2月23日火曜日

KOBUSHI mode

前回の記事で書いたFM音源の仕組みを使って、東方VGSにKOBUSHIモードという機能を入れてみました。KOBUSHIというのは演歌のこぶし(小節)から付けた名前ですが、厳密には演歌のこぶしとは若干違います。(単に音をビブラートさせているだけです)

ついでに、Google Play とかで「KOBUSHI」で検索すると何故か太極拳関連のアプリがよくヒットするのですが、太極拳のシンボルマークによく陰陽マーク(?)が見られるので、東方とも相性が良かろうと。
コレとか
(陰陽マークって太極拳のシンボルマークなんですかね)

KOBUSHIモードを入れたAndroid版の東方VGSは昨日リリース済みで、iOS版は昨夜未明に審査に出したところです。(追記: 2016.02.25 released)

KOBUSHIモードで与えているモジュレータのパラメタは、vgs-bgm-decoderのソースコードを参照。
https://github.com/suzukiplan/vgs-bgm-decoder/blob/master/src/vgsdec.c
※VGSDEC_REG_KOBUSHI という名称のレジスタでON/OFF可能な仕様

若干意図した通りの時間経過による波形加工ができていなかったりしますが、お遊び機能なのでまぁ良いかなと。(後でも直すかも)

モジュレータに与えるパラメタを変えることでもっと色々なパターンのKOBUSHIが作れたりします。(KOBUSHIパラメタをお好みに調整できる機能は後で入れるかもしれません)

このKOBUSHIパラメタの調整というのは、要するにFM音源に与える音色パラメタを調整することとだいたい同義です。実際のFM音源とKOBUSHI音源の違いとしては、KOBUSHIの場合、音を揺らす装置(モジュレータ)が1機しか付いていない点かな。つまり、KOBUSHI音源は2オペレータ(1キャリア, 1モジュレータ)のFM音源ということになります。

有名どころのFM音源のオペレータ数としては、DX7が6オペレータ(1キャリア+5モジュレータ)、YM-2203が4オペレータ(1キャリア+3オペレータ)とかだったと思います。オペレータが3機以上あれば、オペレータの並び順(FM音源の世界ではアルゴリズムと呼ばれている)を変えることができたりします。

本格的なFM音源にすると、東方VGSの元データを弄らずに加工することが難しくなるので、再アレンジが必要になりそうな感じですが、それもまた一興かなと。

2016年2月20日土曜日

FM音源を作ってみる

英雄伝説4の原曲をiTunesで買ってみて聴き倒してみたのですが、やっぱりFM音源って良いですね。

なので、FM音源を作ってみたくなりました。
まずは、基本的な仕組みをYAMAHAの記事(以下)で確認。

FM音源とは

YAMAHAの記事に書いてあることを一言で纏めてみると「FM音源=波形を揺らしたもの」ということです。VGSの波形メモリ音源の場合、三角波、矩形波、ノコギリ波、ノイズの4種類の波形テーブルを持っていますが、これらの波形の読み込み方を変えることで波形を揺らすことができます。

波形の揺らし方

それでは、どうやってやるのか?一応、その辺の仕組みもYAMAHAの記事に書いてありますが、ちょっと専門用語が多くて分かり難い。そこら辺の仕組みはWikipediaで数式を確認することで理解できました。

サイン波は、その名の通り sin(r) で求めることができます。sin関数の引数r(ラジアン値)は時間経過で増加させるのですが、増加させる値が大きければ音が波の周期が短く(音が高く)なり、小さくすれば波の周期が長く(音が低く)なります。

Wikipediaに書かれていた数式を見れば分かるように、sin関数の引数内βsin(2πMt)という別のsin関数で求まる値を加算しています。こうすることで元のAsinのラジアン値の進み方に揺らぎが生まれます。つまり、音が揺れます。

実際に揺らしてみる

先日記事にしたVGS-SPUを使って、実際に波形を揺らして鳴らしてみます。
上記プログラム中で使っている table.h は コチラ
普通に math.h の sin関数 でも良いのですが、それだと浮動小数点を扱う必要があるし、関数呼び出しのオーバーヘッドもバカにならないので、固定小数点で扱えるsin関数テーブルみたいなものです。ついでに、sin(サイン波)だけではなく、矩形波とノコギリ波と音程を求めるためのラジアン値増分も入れてあります。

2016年2月17日水曜日

Androidで目覚ましアプリとか入れない方が良いんじゃないですかね

目覚まし時計って、携帯電話の使用用途としてかなり重要な機能だと思います。ガラケーの頃は、少なくとも私が持っていた機種には全て付いていました。しかし、私が使っているAndroid端末(Android 4.4)には目覚まし時計はOSの標準機能として提供されていません。

そのため、目覚まし時計の機能を使うだけのためにガラケーを使い続けていたのですが、昨夜そのガラケーがご臨終されてしまったので、仕方なくアプリの目覚めし時計を使ってみることにしました。

使用してみたアプリは下記です。
https://play.google.com/store/apps/details?id=com.apalon.myclockfree

1000万DL以上されていて評価も高いので、これなら大丈夫だろうと...

しかし、トラブルは起きました。

翌朝、指定時刻になってもアラームが鳴りません。
何故なら、Android本体がバッテリー0%で落ちていたので。

私のAndroid端末は、かなり電池持ちが良いので、標準的な使い方なら、だいたい2日に1回ぐらい充電すれば事足ります。Androidの目覚ましを設定したその夜は、バッテリー残量が70%程度残っていたので、充電せずに就寝したのがマズかった。(多くの人は、寝る前にAndroidを充電した状態にすると思うので気づき難いかもしれませんね)

何故、私がAndroidの目覚ましアプリを信用していなかったのかというと、バックグラウンドで動作するアプリのプロセスを、OSから殺されずに存命させる手段を私が知らないからです。(バックグラウンドで動作するアプリを開発しているのでその辺の事情をよく知っているつもり)

OSから不要プロセスとして殺されないようにするには、何かしらのタスクを動かし続ける必要があります。タスクを動かし続ければ、当然ぐんぐん電池が減っていく訳です。(その減り方が想定以上に最悪だったためトラブった)

目覚まし時計のアプリが正常に動作できるようにするには、休眠状態でもOSから殺されず、かつ、指定時刻には正常に動く必要があります。その点を解決するには、次の何れかの機能をOSが提供している必要があります。
・目覚まし時計はOSの機能の一部として提供されている
・定時実行タスクとして登録する機能(cronのようなもの)をOSが提供する

Androidにはそのどちらの機能もありません。
後者の機能は悪用の余地が多いと思うので、実装されたら嫌だな...

ちなみに、iOSの場合は、OSの標準機能として目覚まし時計(アラーム)があるので、それを使う分には問題無いと思います(が、サードパーティー製の目覚ましアプリは基本的に信用できないと思っています)。

[追記] push通知でやれば実現できなくもないかと一瞬思ったけど、push通知だとアプリが立ち上がる訳ではないからダメか(ついでに、それだけのためにサーバーを立てるのもそもそもアホらしい気もする)

2016年2月14日日曜日

1996年が20年前な件

え、割と最近じゃね?
とか言い出したりしたらもうオッサンですね。
おぉ、怖い怖い。

1996年といえば、東方Project第一弾(東方靈異伝)が東京電機大学の文化祭に展示されたりとか。ですが、その辺のネタには触れません。というより、当時東方Projectの存在を知らなかったので、触れようがありません。(私が最初に東方Projectを知ったのは2002年の新作から)

1996年といえば、日本ファルコムの英雄伝説4が発売された年ですね。
発売日に予約して買いました。
久々に音楽が聴きたくなって iTunes で買ってみました。(全曲セットで1800円)

このゲームの凄いところは、ストーリーその他は全く思い出せないのですが、音楽だけは未だに鮮明に覚えているということ。(無意識に似ているモチーフが自分の曲で使われたりすることもある)

ストーリーとかは多分プレイすれば思い出せると思います。
もう一度プレイしたいとは思いませんが。

音楽を未だに鮮明に覚えているのは、絵や音楽は脳内で再生し易い→気に入ったものは日常的に反復再生され続ける→記憶から追い出され難いみたいな感じではないでしょうか。

あと、コレが私にとって「真っ当に遊んだ」最後の市販ゲームだったからというのも大きいです。記憶を上書きする材料がほぼ無くなってしまったから、鮮明に残り続けたのかもしれません。これ以降にも何本か市販ゲームは買って遊びましたが、遊んだ記憶が残っていません。(遊んだ記憶が残る次のゲームに出会うのは、それから12年先の2008年〜)

ストーリーは覚えていませんがw

ストーリーというのは私にとって然程重要なものではありません。音楽やグラフィックを引き立てるため、ゲームのストーリーはシンプルな方が良いと思います。ストーリーをメインで楽しみたければ、ゲームよりも映画、小説、漫画などの方が適しています。ストーリーメインなら、むしろ、わざわざ操作が必要なのは面倒臭い。

vgs-spuで始めるサウンドプログラミング

サウンドプログラミングは割と敷居が高いと思われがちですが、その原因は音を鳴らすまでがやたらと難しいためだと思います。これは今も昔も変わらないことです。昔はパソコンに搭載されている石の仕様を理解する必要があったので、実際かなり大変でした。

しかし、今のパソコンやスマートフォンであれば、少なくとも石(H/W)の違いを意識する必要はありません。Windows、Mac OS X、Linux、UNIX、Android、iOSなどで、音を鳴らす基本的な仕組みは全部同じですが、それぞれのOSが提供する「音を鳴らす方法」が以下のように多様にあります。
  • Windows: WaveMapper や DirectSound
  • Mac OS X, iOS: AudioUnit や OpenAL
  • Linux: ALSA; Advanced Linux Sound Architecture
  • Android: OpenSL/ES (他)
  • UNIX: OSS; Open Sound System
全部覚えるのは面倒臭いです。全部どころか、一つマスターするのも結構大変かもしれません。(やれる事はだいたい全部同じなので、一つマスターするだけで全部マスターするのは容易いですが)

VGSではこの辺りの実装を Sound Abstraction Layer (SAL) という形で抽象化しましたが、今回、その SAL を更に汎用的な形で独立させてみました。

VGS - Sound Processing Unit (SPU)
https://github.com/suzukiplan/vgs-spu

まだこの記事を書いている段階では WIP にしていますが、とりあえず Windows と Mac OS X では動きました。VGS-SPUは、全OS共通の「音を鳴らす方法」を提供します。これを使えば、敷居が高いと思われがちな サウンドプログラミング の敷居が幾分か低くなります。

どの程度低いかは、VGS-SPUの example を見ていただければ分かると思います。

この example では、buffering というコールバック関数で波形(440Hz = ラ の矩形波)を書き、main関数で VGS-SPU を起動、スリープ、停止という手続きを実行しています。

「音を鳴らす」というのは要するに波形データの変化(PCM)を書くことです。その辺のことは情報処理の教科書的なもので見たことがあると思いますが、「そのデータを何処に書くの?」ということは恐らく情報処理の教科書的なものには書いてないと思います。「何処に書くのか」は、前述の各OSが提供しているサウンドAPI毎に異なるし、また、あまり纏まった資料も無い(個々のAPI毎にかなり無駄に分厚い専門書とかなら少ないがある)ので、実際に音(PCM)を書くところまで辿り着くのが結構大変です。

しかし、VGS-SPUなら「vgsspu_startを呼ぶ」「コールバックで音を書く」「vgsspu_endで終わる」という極めてシンプルな3ステップだけでサウンドプログラミングの入り口に辿り着くことができます。

そして、VGS-SPUを通して音の鳴らし方のイメージが掴めてきたら、VGS BGM Decoderを見てみると良いです。

VGS BGM Decoder
https://github.com/suzukiplan/vgs-bgm-decoder

VGS-SPUは音を書くための方法で、VGS BGM Decoderは書く音を生成するコーデックと呼ばれるものです。コーデックという言葉はマルチメディア系に詳しい方なら聞いたことがあるかもしれませんが、サウンドの世界では符号化されたデータ(VGSなら .BGM形式)をリニアPCMへ変換するもの(デコーダ)や、何がしかのデータを符号化するもの(エンコーダ)があります。

VGS BGM Decoderにとってのエンコーダは MML(テキスト)を .BGM形式に変換するMMLコンパイラのことですね。VGSのMMLコンパイラについても独立したリポジトリに切り出してみました。

VGS MML Compiler (encoder)
https://github.com/suzukiplan/vgs-mml-compiler

2016年2月12日金曜日

VGSの分割

1週間ほど前、突如として海外(中国)のエンジニアさんから、

「VGSのオーディオプラグインを作りたいんだけど、ソースが汚くてツライ」(意訳)

というメールが飛んできて、まぁ普段なら英語メールはスルーすることが多いのですが、割と丁寧に書いてあったので読んでみました。日本を含めて私にこういう技術ネタ的なメールを送ってくる人というのは稀な存在ですし。(ちなみにGitHubのプロフィールによると、日本でいうところのNTT的な感じの会社のエンジニアさんらしい。あぁ、なるほど)

あくまでもVGSは趣味で作っているものですが、オープンソースで公開している以上、あまり恥ずかしい状態で晒しておくのもアレだろうと思い、「よっしゃリファクタしたろか」というノリでVGSのソースコードからBGMデコーダ部分の実装を切り離す作業をやっていたりしました。

それがこのリポジトリ
https://github.com/suzukiplan/vgs-bgm-decoder

ちゃんと綺麗に書いています。
テストも書いています。
本業でプログラムを作る時とだいたい同じノリで構成管理もしています。

ついでに、VGSのMMLもダイレクトに再生したいとのことなので、インメモリでMMLをコンパイルできるモノも作ってみました。
https://github.com/suzukiplan/vgs-mml-compiler

コレを使えば、VGSの .MMLファイル、.BGMファイル、vgsファイル を読み込んで波形データ(PCM)を生成することができます。vgs-bgm-decoderのexampleとして、.BGMファイル や .vgsファイル をwaveファイル形式に変換するCLIなんかを作っておきました。

そして、そのエンジニアさんが作ったオーディオプラグインというのがコチラ
https://github.com/AmamiyaRinyuki/vgs-bgm-plugins
※今の所、AudaciousというLinux用のオーディオプレイヤ用のプラグインがあるようです。

今回作った vgs-bgm-decoder を使えば、こういうプラグインの開発は割と簡単にできると思います。iTunes(QuickTime?)のプラグインとか作れれば胸が熱くなるなと思ったのですが作り方がよく分からなかった。

これぐらいの規模感でVGSの部品をどんどん分割していこうと考えています。(分割したものはVGS mk-II SRに統合するつもりですが、もっと柔軟に使える新しいVGSを作ってみようかみたいなことを思ったりもしています)

2016年1月11日月曜日

VGS BGM Player収支報告

VGS BGM Playerではマネタイズをしていますが、その目的はランニングコストの回収です。
という訳で、だいたい運用1か月ぐらいでの収支報告でもしておきます。

【収入の部】

①広告収入
84円

インプレッション(表示回数)は1641回なので、リクエストRPMは54円ですね。デバッグ時のインプレッションを含んでいる(w)ので、だいたいこんなもんでしょうか。ちなみに、SUZUKI PLANの広告アプリ全体平均のリクエストRPMはだいたい140円でう。

②アプリ内課金収入
2本(だいたい1ドル40セント)

売れた・・・だと・・・
これは売れない(売れても年間1〜2本)という想定でした。
早くも年間目標可達!
本当にありがとうございます。

【支出の部】

③サーバー費用
250円

④ドメイン費用は含めない
(これはSUZUKI PLAN全体のアプリIDと共用なのでVGS BGM Player専用ではない)

⑤Appleアカウント
(これもSUZUKI PLANのiOSアプリ全体と共用なので単体決算はしない)

⑥プロモ費用
プライスレス
(というより何もやっていない)

1ドルは今だいたい120円ぐらいだろうか?
1.40ドルなら168円ぐらいですかね?
という訳で今月の収支は 2円の黒字 です。

ナイスです。
まぁ、サーバー費用はVGS BGM Player(というよりsuzukiplan.com)を作ろうと思い立ってから半年以上の不稼働期間があったので、厳密には思いっきり赤なのですが、その辺は娯楽ということで問題ありません。可処分所得(お小遣い)の範囲でクリアです。

suzukiplan.comで東方VGSの曲を配っていて、それ自体はタダだけど、二次創作ガイドライン的にそれがOKなのかよく分からないので、あまり大きな黒字を出すのは良くないと思っています。

理想的には±0円のライン。
見事に狙い通りです。
ハンター冥利に尽きます。

黒字になりそうだったらサーバーを増強するなり、広告出稿して調整するなど、手は幾らでもあります(広告出稿は数万程度の小額ならほぼ効果が出ないことは過去数回のテスト出稿で検証済み)。

アプリ内課金は1人当たりどんなにぶっ込んでも1300円ぐらいにしか行かないようにしてあるので青天井対策もバッチリです。

理想的には元気に働ける内は収支0で、エンジン切れになったらギリギリ食べていける程度の収入が入る感じ。私は若干生き急いでいる感があるので、ゴールは割と近いかもしれない。自愛しようと心がけているつもりだが、根っからのマゾヒスト性格が裏目に出ている感が否めない。

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

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