DirectSound2

singed 8bitは素のデータ構造であって、保存形式としては全然向いていません。もし30分の音楽データを入れたいなと思った場合は30分*60秒=1800秒、1800*16384バイト=29,491,200バイトとなって圧迫感が半端ないです。そこで圧縮しつつもCPU使用率を取らないライブラリを紹介します。

8ad codec

https://pineight.com/gba/#8ad
ADPCM techniques and 6 percent of the GBA's CPU time.がウリです。非常に扱いやすくソースコードも短かった為、サンプルプログラムNO.108 diabo_gbaやNO.106 kanon_gbaに採用しました。オススメの1つです。

MaxMod

https://maxmod.devkitpro.org/
https://github.com/devkitPro/maxmod
devkitProに標準装備されていて非常に有名です。数少ないdevkitProのexamplesプログラムの1つです。libmm.aを組み込みも方法となるmakefileもあるので簡単な方ではあります。MOD, S3M, XM, and ITとwavも対応しています。

Apex Audio System

https://github.com/stuij/apex-audio-system
当時有名でしたけれど詳しくは不明です。MOD playing routines and support for up to 16 channels.

Krawall

https://github.com/sebknzl/krawall
当時有名でしたけれど詳しくは不明です。XM/S3M Modplayer.

GBT Player

https://github.com/AntonioND/gbt-player
DirectSoundと関係ないですけれどゲームボーイサウンドとしてならこちらが有名です。GB Studioに組み込まれているのでサウンドエディタはGB Stdioで編集して、再生はライブラリで行うということが可能になりそうです。詳しくは未調査です。

ところでMod多くない?

海外圏はmidi文化ではなくmod文化の為、ということなんだと個人的に解釈しています。まーしょうがないですよ。mod編集エディタで作る方が簡単だと思います。ここではMaxModのサンプルプログラムを用意しました。libmm.aを組み込むだけですと味気ないので、MaxModソースコードをコンパイルして、libgccもお世話にならない作りをしています。

MaxModのコンパイルメモ

サンプルプログラム

#include "libmm/maxmod.h"
#include "lib/gba.h"
#include "irq.arm.h"
#include "bg.h"
#include "key.h"
#include "res.h"

//---------------------------------------------------------------------------
// maxmodライブラリ内の非公開関数
u32 mmMixerChannelActive(mm_word channel);

//---------------------------------------------------------------------------
// 効果音の登録(id, rate, handle, volume, panning)
mm_sound_effect ambulance = { {SFX_AMBULANCE}, (int)(1.0f * (1<<10)), 0, 255, 0 };
mm_sound_effect boom = { {SFX_BOOM}, (int)(1.0f * (1<<10)), 0, 255, 255 };

// sound effect handle (for cancelling it later)
mm_sfxhand amb = 0;

//---------------------------------------------------------------------------
IWRAM_CODE int main(void)
{
	REG_WSCNT = 0x4317;

	BgInit();
	KeyInit();
	IrqInit();

	mmInitDefault((mm_addr)soundbank_bin, 8);
	mmStart(MOD_FLATOUTLIES, MM_PLAY_LOOP);

	BgDrawPrintf(0, 0, "MaxMod Audio demo");
	BgDrawPrintf(1, 2, "Hold  A for ambulance sound");
	BgDrawPrintf(1, 3, "Press B for boom sound");
	BgDrawPrintf(1, 4, "Press L for music stop");
	BgDrawPrintf(1, 5, "Press R for music start");

	BgDrawPrintf(1, 8, "CPU Usage");
	BgDrawPrintf(1, 9, " +2.6 percent BASE");
	BgDrawPrintf(1, 10, " +2   percent 1ch (max 8ch)");


	for(;;)
	{
		VBlankIntrWait();

		// start vcount 0
		while(*(vu16*)0x4000006 != 0) {};

		// パレット0を変更してcpu使用率の可視化をします
		// mmVBlank関数は本来、vblank割り込み中に処理を行います

		*(vu16*)0x5000000 = RGB5(31, 0, 0);
		mmVBlank();
		*(vu16*)0x5000000 = RGB5(0, 0, 31);
		mmFrame();
		*(vu16*)0x5000000 = RGB5( 0, 0, 0);


		vu32 i, ch = 0;
		for(i=0; i<8; i++)
		{
			if(mmMixerChannelActive(i) != 0)
			{
				ch++;
			}
		}
		BgDrawPrintf(1, 12, "Channel Active:%d", ch);


		KeyExec();
		u32 off = KeyGetOff();
		u32 trg = KeyGetTrg();

		if(trg & KEY_A) amb = mmEffectEx(&ambulance);
		if(off & KEY_A)       mmEffectCancel(amb);

		if(trg & KEY_B) mmEffectEx(&boom);
		if(trg & KEY_L) mmStop();
		if(trg & KEY_R) mmStart(MOD_FLATOUTLIES, MM_PLAY_LOOP);
	}
}

音楽データを加工するにはmakefileで以下のようにするといいと思います。mmutil.exeと呼ばれる専用ツールが使われています。

soundbank.s : $(WAVFILES) $(MODFILES)
	@echo \# converting $(WAVFILES) $(MODFILES)
	@mmutil $^ -osoundbank.bin -hsoundbank.h
	@bin2s soundbank.bin > $@

動作画面

1.png

履歴


トップ   一覧 検索 最終更新   ヘルプ   最終更新のRSS