#author("2023-05-21T01:00:59+09:00","","")
* DirectSound2 [#bf4bc923]
音楽データのsinged 8bitは、素の構造であって保存形式としては全然向いていません。もし30分の音楽データを用意した場合は30分*60秒=1800秒、1800*16384バイト=29,491,200バイトとなって現実的ではありません。そこで圧縮しつつもCPU使用率を取らないライブラリを紹介します。

** 8ad codec [#r02fc646]
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 [#ia541121]
https://maxmod.devkitpro.org/~
https://github.com/devkitPro/maxmod~
devkitProに標準装備されています。examples内にサンプルコードもあったりします。MOD, S3M, XM, and ITとwavも対応しています。

** Apex Audio System [#efdfcaa0]
https://github.com/stuij/apex-audio-system~
詳しくは不明です。MOD playing routines and support for up to 16 channels.

** Krawall [#x576fed7]
https://github.com/sebknzl/krawall~
詳しくは不明です。XM/S3M Modplayer.

** GBT Player [#j68677c7]
https://github.com/AntonioND/gbt-player~
DirectSoundと関係ないですけれどゲームボーイサウンドとして有名です。詳しくは不明です。

** ところでMod多くない? [#xd081c74]
海外圏はmidiではなくmod文化の為、ということだと個人的に解釈しています。このチュートリアルではMaxModのサンプルプログラムを用意しました。libmm.aを組み込むだけですとdevkitproのサンプルとネタが被るので、MaxModソースコードを直接コンパイルして、libgccもお世話にならない作りにしました。

** MaxModのコンパイルメモ [#z0fc8c51]
- 1.ASFLAGS~
MakefileのASFLAGSにSYS_GBAを組み込みます。MaxModの*.sファイルにDS用かGBA用かの判定がある為です。
 ASFLAGS = -DSYS_GBA

- 2._call_via_r7, _call_via_r1~
gcc_patch.sを作成してこちらで経由させます。
 // 2023/05/18 reject libgcc.
 // patched -> _call_via_r7, _call_via_r1, malloc
 
 
 	.align 0
 	.global _call_via_r7
 	.thumb_func
 
 _call_via_r7:
 	bx r7
 
 
 	.align 0
 	.global _call_via_r1
 	.thumb_func
 
 _call_via_r1:
 	bx r1

- 3. ソースコードの変更~
mm_init_default.sの71行目に使用するチャンネル数(最大8)をmallocさせています。こちらもpatch当てています。
 	mov	r6, r1				// r6=#channels
 	ldr	r0,=MM_SIZEOF_MODCH+MM_SIZEOF_ACTCH+MM_SIZEOF_MIXCH
 	mul	r0, r6
 	ldr	r4,=mixlen
 	add	r0, r4
 //	bl	malloc		patched 2023/05/18
 	bl	MallocPatch

- 4. 自作malloc~
自前に容量を確保します。ちなみに8chで1792バイトでした。
 #include "malloc.h"
 
 //---------------------------------------------------------------------------
 u8 MallocMem[2000];
 
 //---------------------------------------------------------------------------
 EWRAM_CODE u32* MallocPatch(u32 size)
 {
 	TRACE("MallocPatch: size=%d\n", size);
 
 	return (u32*)MallocMem;
 }

** サンプルプログラム [#m72fe206]
 #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と呼ばれる専用ツールがあるので1つのバイナリデータにして加工してくれます。

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

** 動作画面 [#u6e9c70b]
#ref(1.png,nolink)

** 履歴 [#gfa4226d]
- 2023/05/18

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