先日、英雄伝説4の原曲集をiTunesで買ってから、ファルコムのFM音源アルバムをiTunesで色々と買い揃えてみました。いや、全部CDで持っているんですけどね。(CDを再生する機械が手元にないから仕方がない)
イース4と風の伝説ザナドゥは、パソコン(PC-98)ではなくPCエンジンが原作なので、原曲 = 波形メモリ音源 or CD-DAですが、PC-98のFM音源(YM2608)で作られた原曲の原曲版です。
98のFM音源で原曲を作ってから波形メモリ音源なり生楽器なりでアレンジしたものをゲームで使っていたようです。チップチューンの頃は、機種毎に音源仕様が全く異なるので、音楽を作る人が最も得意な環境で最初に作ってから、ターゲット機種向けにアレンジするということは割とよくあったのではないかと思います。
こういうのは最近無いですね。
世界樹の迷宮(任天堂DS)など、PC-8801のサンプリング音を使ってBGMを作ったFM音源原曲(?)の比較的新しいゲームとかならあったりしますが。去年YAMAHAがDX refaceという最新のFM音源をリリースしたりした(恐らく現代でもかなり戦力になる音源だと思う)ので、FM音源で作られたゲーム音楽は今後もチラホラ出てくるのではないだろうかと思っています。サンプリング音や生楽器よりも音的にゲームに向いていると思うので。
ただ、私の言う「こういうの」というのは、そういうことではなく、原曲の原案を敢えて8bit機、16bit機のチップチューン音源で作ってから、最新のサンプリング音源で曲を作り直すということ。一見すると無駄手間のように見えます...というか、無駄以外の何物でも無いかもしれません。
いや、もしかすると私が知らないだけで、作曲の最初期の段階では MSX + FB-01(※操作にMSXが必要なオーパーツ的なFM音源)で作り、それを基に最新の機材でアレンジしたものを最終納品物にしているプロが今でも居るのかもしれません。
それなら、原案版のサントラも出した方が売り上げ的な意味でも良いと思うのですが、そういうのが無いということは、やっぱりそういう人は居ないのだろうか。俄には信じ難いのですが。少なくとも私は一見すると無駄手間のように見えるその手順を踏まないと作れないので。
何故か?
うまく説明できないのですが、ノリとしてはこんな感じだろうか。
2016年2月27日土曜日
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の元データを弄らずに加工することが難しくなるので、再アレンジが必要になりそうな感じですが、それもまた一興かなと。
ついでに、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を使って、実際に波形を揺らして鳴らしてみます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pthread.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <ctype.h> | |
#include "vgsspu.h" | |
#include "table.h" /* S:サイン波, Q:矩形波, W:ノコギリ波, A:音階テーブル */ | |
#define SAMPLING_RATE 44100 | |
#define BIT_RATE 16 | |
#define CHANNEL 1 | |
struct VgsPsgContext { | |
unsigned int hz; | |
int r; | |
int m; | |
int scale; | |
}; | |
static struct VgsPsgContext _context; | |
static struct VgsPsgContext* _ctx = &_context; | |
void cb(void* buffer, size_t size) | |
{ | |
int i, w; | |
short* buf = (short*)buffer; | |
int s = 0; | |
int fm; | |
size >>= 1; | |
for (i = 0; i < size; i++, buf++, _ctx->hz++) { | |
fm = _ctx->r; // キャリア | |
fm += S[_ctx->m >> 8] << 12; // モジュレータ1(サイン波) | |
fm += Q[_ctx->m >> 8] << 12; // モジュレータ2(矩形波) | |
fm += W[_ctx->m >> 8] << 12; // モジュレータ3(ノコギリ波) | |
// バッファオーバフロー防止 | |
if (fm < 0) { | |
fm += 4410 * 256; | |
} else { | |
fm %= 4410 * 256; | |
} | |
// 求まった値を使ってテーブルから波形を読んで書く | |
fm >>= 8; | |
w = S[fm] << 4; | |
*buf = (short)w; | |
// キャリア & モジュレータ それぞれの周波数を進める | |
_ctx->r += A[_ctx->scale]; | |
_ctx->r %= 4410 * 256; | |
_ctx->m += A[_ctx->scale]; | |
_ctx->m %= 4410 * 256; | |
} | |
} | |
int main(int argc, char* argv[]) | |
{ | |
char buf[1024]; | |
void* vgsspu = vgsspu_start2(SAMPLING_RATE, BIT_RATE, CHANNEL, 4096, cb); | |
_ctx->scale = 40; | |
while (1) { | |
printf("COMMAND: "); | |
memset(buf, 0, sizeof(buf)); | |
if (NULL == fgets(buf, sizeof(buf) - 1, stdin)) break; | |
if ('q' == buf[0]) break; | |
if (isdigit(buf[0])) { | |
_ctx->scale = atoi(buf); | |
} | |
} | |
return 0; | |
} |
上記プログラム中で使っている table.h は コチラ。
普通に math.h の sin関数 でも良いのですが、それだと浮動小数点を扱う必要があるし、関数呼び出しのオーバーヘッドもバカにならないので、固定小数点で扱えるsin関数テーブルみたいなものです。ついでに、sin(サイン波)だけではなく、矩形波とノコギリ波と音程を求めるためのラジアン値増分も入れてあります。
普通に 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通知だとアプリが立ち上がる訳ではないからダメか(ついでに、それだけのためにサーバーを立てるのもそもそもアホらしい気もする)。
そのため、目覚まし時計の機能を使うだけのためにガラケーを使い続けていたのですが、昨夜そのガラケーがご臨終されてしまったので、仕方なくアプリの目覚めし時計を使ってみることにしました。
使用してみたアプリは下記です。
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
ストーリーというのは私にとって然程重要なものではありません。音楽やグラフィックを引き立てるため、ゲームのストーリーはシンプルな方が良いと思います。ストーリーをメインで楽しみたければ、ゲームよりも映画、小説、漫画などの方が適しています。ストーリーメインなら、むしろ、わざわざ操作が必要なのは面倒臭い。
とか言い出したりしたらもうオッサンですね。
おぉ、怖い怖い。
1996年といえば、東方Project第一弾(東方靈異伝)が東京電機大学の文化祭に展示されたりとか。ですが、その辺のネタには触れません。というより、当時東方Projectの存在を知らなかったので、触れようがありません。(私が最初に東方Projectを知ったのは2002年の新作から)
1996年といえば、日本ファルコムの英雄伝説4が発売された年ですね。
発売日に予約して買いました。
久々に音楽が聴きたくなって iTunes で買ってみました。(全曲セットで1800円)
このゲームの凄いところは、ストーリーその他は全く思い出せないのですが、音楽だけは未だに鮮明に覚えているということ。(無意識に似ているモチーフが自分の曲で使われたりすることもある)
ストーリーとかは多分プレイすれば思い出せると思います。
もう一度プレイしたいとは思いませんが。
音楽を未だに鮮明に覚えているのは、絵や音楽は脳内で再生し易い→気に入ったものは日常的に反復再生され続ける→記憶から追い出され難いみたいな感じではないでしょうか。
あと、コレが私にとって「真っ当に遊んだ」最後の市販ゲームだったからというのも大きいです。記憶を上書きする材料がほぼ無くなってしまったから、鮮明に残り続けたのかもしれません。これ以降にも何本か市販ゲームは買って遊びましたが、遊んだ記憶が残っていません。(遊んだ記憶が残る次のゲームに出会うのは、それから12年先の2008年〜)
ストーリーというのは私にとって然程重要なものではありません。音楽やグラフィックを引き立てるため、ゲームのストーリーはシンプルな方が良いと思います。ストーリーをメインで楽しみたければ、ゲームよりも映画、小説、漫画などの方が適しています。ストーリーメインなら、むしろ、わざわざ操作が必要なのは面倒臭い。
vgs-spuで始めるサウンドプログラミング
サウンドプログラミングは割と敷居が高いと思われがちですが、その原因は音を鳴らすまでがやたらと難しいためだと思います。これは今も昔も変わらないことです。昔はパソコンに搭載されている石の仕様を理解する必要があったので、実際かなり大変でした。
しかし、今のパソコンやスマートフォンであれば、少なくとも石(H/W)の違いを意識する必要はありません。Windows、Mac OS X、Linux、UNIX、Android、iOSなどで、音を鳴らす基本的な仕組みは全部同じですが、それぞれのOSが提供する「音を鳴らす方法」が以下のように多様にあります。
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
しかし、今のパソコンやスマートフォンであれば、少なくとも石(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 を見ていただければ分かると思います。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef _WIN32 | |
#include <windows.h> | |
#else | |
#include <unistd.h> | |
#endif | |
#include <stdio.h> | |
#include "vgsspu.h" | |
#ifdef _WIN32 | |
static void usleep(int usec) | |
{ | |
Sleep(usec / 1000); | |
} | |
#endif | |
static unsigned int hz; | |
static unsigned int pw = 22050; | |
static void buffering(void* buffer, size_t size) | |
{ | |
short* sbuf = (short*)buffer; | |
size_t s2 = size >> 1; | |
size_t s1; | |
for (s1 = 0; s1 < s2; s1++, sbuf++, hz++) { | |
if (hz % 440 < 220) { | |
*sbuf = (short)((16384 * pw) / 22050); | |
} else { | |
*sbuf = (short)((-16384 * pw) / 22050); | |
} | |
if (pw) pw--; | |
} | |
} | |
int main(int argc, char* argv[]) | |
{ | |
void* context = vgsspu_start(buffering); | |
if (NULL == context) { | |
puts("failed"); | |
return -1; | |
} | |
usleep(1000000); | |
vgsspu_end(context); | |
return 0; | |
} |
この 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を作ってみようかみたいなことを思ったりもしています)
「VGSのオーディオプラグインを作りたいんだけど、ソースが汚くてツライ」(意訳)
というメールが飛んできて、まぁ普段なら英語メールはスルーすることが多いのですが、割と丁寧に書いてあったので読んでみました。日本を含めて私にこういう技術ネタ的なメールを送ってくる人というのは稀な存在ですし。(ちなみにGitHubのプロフィールによると、日本でいうところのNTT的な感じの会社のエンジニアさんらしい。あぁ、なるほど)
あくまでもVGSは趣味で作っているものですが、オープンソースで公開している以上、あまり恥ずかしい状態で晒しておくのもアレだろうと思い、「よっしゃリファクタしたろか」というノリでVGSのソースコードからBGMデコーダ部分の実装を切り離す作業をやっていたりしました。
それがこのリポジトリ
https://github.com/suzukiplan/vgs-bgm-decoder
ちゃんと綺麗に書いています。
テストも書いています。
本業でプログラムを作る時とだいたい同じノリで構成管理もしています。
ついでに、VGSのMMLもダイレクトに再生したいとのことなので、インメモリでMMLをコンパイルできるモノも作ってみました。
https://github.com/suzukiplan/vgs-mml-compiler
そして、そのエンジニアさんが作ったオーディオプラグインというのがコチラ
https://github.com/AmamiyaRinyuki/vgs-bgm-plugins
※今の所、AudaciousというLinux用のオーディオプレイヤ用のプラグインがあるようです。
今回作った vgs-bgm-decoder を使えば、こういうプラグインの開発は割と簡単にできると思います。iTunes(QuickTime?)のプラグインとか作れれば胸が熱くなるなと思ったのですが作り方がよく分からなかった。
これぐらいの規模感でVGSの部品をどんどん分割していこうと考えています。(分割したものはVGS mk-II SRに統合するつもりですが、もっと柔軟に使える新しいVGSを作ってみようかみたいなことを思ったりもしています)
登録:
投稿 (Atom)
合理的ではないものを作りたい
ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...
-
家電量販店のPCゲームパッドコーナーに行くと、軒並みWindows用のゲームパッドしか売っていません。稀に「Mac OS X対応」を謳っているゲームパッドも置いてありますが、実際に動かしてみると妙に誤動作をして更にガッカリしたりとか(経験済み)。 色々と試してみたのですが、最...
-
ゲームボーイのCPUについて、誤った技術情報が検索トップの方に表示されるので、私が把握する限りでZ80との仕様差を書いておきます。 ゲームボーイのCPUとは? ☓ 8080 ☓ Z80 ○ 8080カスタム or Z80カスタム(正確にはSHARPのLR35902) ...
-
MSX開発の関係者を匂わせるタイトルかもしれませんが、私は全然関係ない(外野)です。 私はマイコン世代(死語)の人間ですが、実はリアルタイムでMSXは触ったことすら無いです。私が最初に触ったパソコンはPC-9801(16bit機)で、8bit機のMSXは触る機会すらありませんでし...