gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Audio > ModPlayer fundamentals

#25480 - ProblemBaby - Mon Aug 23, 2004 8:54 pm

Hi again

to DekuTree: If you read this, then maybe this is stuff you are going to take up in your article, if that is the case you can just say that and I can wait.

Ok:
Ive started to explore the XM-format and now most of the things (except for effects).

Iam using the 18157hz, Update on VBlank -style.
I want to have a nice structure in my replayer and I dont really know how people most often do.
My plan is to have a structure like

u32 SampleAddress[12];
u32 SampleLength[12];
u32 SampleCounter[12];
u16 Frequency[12];
u8 Volume[12];
s8 Panoration[12];

12 = MAX_CHANNELS
is twelve to much?
Ive calculated and found out that Ive to write 304(size of buffers)*12(MAX_CHANNELS)*2(left and right)
times to the buffers is that to much for one cycle. if it is written in ARM asm and putted in iwram?

then do you think the layout is good?
Then when I go through the pattern I just update this variables (Maybe have to add some for effects later) and oh I think you understand.

Some feedback would be nice!

#25481 - DekuTree64 - Mon Aug 23, 2004 9:22 pm

Yeah, the hardest part of writing a music player for the first time is getting the whole structure worked out, because there's really no best place to start. The next tutorial is on writing a converter program to set up all the data you'll need for the player. It should be one of the most useful of the series, because you don't know what kind of data you need until you write a player, and you can't write a player without some data to test it, so normally you have to rewrite at least one of them after you see how things are going to end up.
I'd planned on doing the start of the player itself at the same time, but seeing as how the article is already getting long and I haven't even gotten past the tricky parts yet, I'll split it up.

As for your design there, you should shove all those variables into a struct and make 12 of them. Much nicer design-wise.
I don't think 12 channels is not too much, but it may be pushing it a little. I managed 16 stereo channels in 20% CPU, but at the cost of having only 16 volume levels. If you can stand cutting that back to 8, you could have 32 volumes, which should sound acceptable at least. The limit comes when you put the left volume in the lower 16 bits of a register, and the right volume in the upper 16 bits. If you multiply an 8-bit sample by that, you get the left and right for the price of one. However, when you add 16 channels together, that's up to 4 bits more used, leaving only 4 of the half-register remaining for volume.
Now that I think about it though, you could sacrifice one cycle per sample per channel to clear some of the lower bits of the top half of the register, and then shift down while you add it to the mix.

Something like
Code:
mul rDest, rSmp, rVol   @left and right
bic rDest, rDest, 0xf0000   @clear some bits so they don't kill the top of the left channel in rMix
add rMix, rMix, rDest, asr #4


Might be worth looking into.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#25484 - ProblemBaby - Mon Aug 23, 2004 10:20 pm

Thanks for that information!
Well I know what you mean
Ive already 12 new questions;)
I Have to ask one for now and then I will promise to wait for the article to answer the rest.
I want to finish my XM-converter my question is if it is good to save the layout of that file with instruments that contains samples or should I make samples of everything when I convert and then refer to the actual sample by a WORD instead of the note/instrument thing (like xm).

Which is best for the future?=)

#25485 - DekuTree64 - Mon Aug 23, 2004 10:43 pm

You mean the instrument sample maps, where playing an instrument at different notes can trigger different samples? That depends on wether you plan to use it. Most likely it would work out better to keep instruments and samples as seperate things, so you stay as close to the original format as possible, just for simplicity's sake. The sample maps take a little memory, but if you're willing to give up a little EWRAM, you can RLE compress them and then they'll usually only take a couple of bytes of ROM, because they're normally one long run of the same sample.
It also adds another layer to your player logic, having to keep track of what instrument and sample each channel is using, but it's all just table lookups and doesn't complicate things much.

I'm currently at work, so no new article progress has been made yet. I'll see if I can get it wrapped up tonight though.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku