DirectSound2

音楽データのsinged 8bit 16384hzは、素のデータであって保存形式として向いていません。もし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に標準装備されていてexamplesフォルダにサンプルコードもあったりします。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と関係ないですけれどゲームボーイサウンドとして有名です。詳しくは不明です。

ところでMod多くない?

海外圏はmidiではなくmod文化の為、ということだと個人的に解釈しています。以下に、MaxModのサンプルプログラムを用意しました。libmm.aを組み込むだけですとdevkitproのサンプルと被るので、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で以下のようにしています。maxmodのmmutil.exeと呼ばれる専用ツールがあるので、1つのバイナリデータに加工してくれます。

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

動作画面

1.png

履歴


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