#author("2023-05-30T11:05:09+09:00","","") #author("2023-05-30T11:06:27+09:00","","") * DirectSound2 [#bf4bc923] 音楽データのsinged 8bit 16384hzは、素のデータであって保存形式として向いていません。もし30分の音楽データを用意した場合は30分*60秒=1800秒、1800*16384バイト=29,491,200バイトとなってしまいます。そこで圧縮しつつもCPU使用率を取らないライブラリを以下に紹介します。上2つは使ったことはありますが他は詳しくありません。ご了承ください。 ** 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. * ところでMod多くない? [#xd081c74] 個人的にはmidiの方が親しみを持つのですけれど、midiフォーマットですとGBサウンドの仕様を満たすのは難しいようです。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}, 1024, 0, 255, 0 }; mm_sound_effect boom = { {SFX_BOOM}, 1024, 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 > $@ もしMaxModを扱うのでしたら[[Maxmod Programming Reference:https://maxmod.devkitpro.org/ref/]]は必読書になると思います。ページの後半が詳しいので読んでみてください。 もしMaxModを扱うのでしたら[[Maxmod Programming Reference:https://maxmod.devkitpro.org/ref/]]は必読書になると思います。ページ後半のGBA Programming Guideが詳しいので読んでみてください。 ** 動作画面 [#u6e9c70b] #ref(1.png,nolink) ** 履歴 [#gfa4226d] - 2023/05/18