#25383 - ProblemBaby - Sat Aug 21, 2004 7:44 pm
It was to expensive to have "real" music so I have decided to make a mod player. I have succeeded to load xm files and I know how I should set up everything.
The hard part is the GBA stuff... I can play a sample with DMA but when I do a mod player I should manually write to FIFO_x, right?
Well I cant get it to work. Here is my interrupt code.
Ive not changed any settings from the DMA example, Ive enabled
interrupts the function is called but it doesnt play anything.
Its very, very bad written cause I just want it to work, optimazation comes later.
r3: a struct that look like this
u32 Active
u32 Address
u32 Length
u32 SampleCounter
r2: 0x4000080
Code: |
LDR r3, =Sound
LDR r2, =REG_SOUNDBASE
LDR r1, [r3]
CMP r1, #1
BNE NoSample
LDR r1, [r3, #12]
LDR r0, [r3, #4]
ADD r0, r0, r1
LDR r0, [r0]
STR r0, [r2, #REG_FIFO_A]
LDR r1, [r3, #12]
ADD r1, r1, #4
STR r1, [r3, #12]
LDR r0, [r3, #8]
CMP r1, r0
BLT NoSample
MOV r1, #4
STR r1, [r3, #12]
MOV r1, #0
STR r1, [r3, #0]
NoSample:
BX lr
|
You probably think that this is thumb code, but it isnt. My ARM knowlegde
sucks so tips how to improve would also be great!
and if you know any tutorial about this topic it also would be nice!
Thanks in advance!
#25384 - DekuTree64 - Sat Aug 21, 2004 8:34 pm
Normally you don't want to write to the FIFO directly. I've gotten it to work before (in C, not ASM), but it super slow. What you want to do is create a buffer and mix sounds into that as needed, and DMA it to the FIFO. Most people just use a simple double buffer where each buffer is long enough for one frame's worth of samples. You can probably find a table of frequency/buffer size combos that times out perfectly with the time between VBlanks in one of the many mixer posts around here, but the most frequently used is 18157Hz, with a buffer of 304 bytes, and the sound timer set to 64612 (which is 65536 - (16777216 / 18157)).
Now, for testing, all you need to do is wait for VBlank, swap the double buffer, and copy in 304 samples from the sound you want to play.
The swap is done just by stopping the DMA, setting the source address to the start of the next buffer, and restarting it.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#25390 - ProblemBaby - Sat Aug 21, 2004 11:04 pm
Thanks a lot!
Ive got it to work Now I just wonder
How to play a sample with a another frequency.
I can change the timer but if I want to play two with different frequencies at the same time.
#25393 - DekuTree64 - Sat Aug 21, 2004 11:15 pm
Just give me a little more time. After replying to your post earler, I decided to write up a little article series on sound system creation, and I have the first issue just about done. Since so many people will likely be tackling it for this compo, and I won't be able to resist answering all the questions, I may as well do it all in one go and have a nice reference for everyone later.
Although the first issue doesn't tackle resampling, so I guess I'll give a quick hint now: Use a fixed point position and increment, so you can play them at different speeds. Then add them together and divide by 2 to prevent overflow and you have the basics of a mixer.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#25394 - ProblemBaby - Sat Aug 21, 2004 11:26 pm
Thanks for the information I solved it.
I aint that experienced in Audio so I had to ask that even cause it was quite simple to find out.
An article serie sounds really nice, Good luck!
#25405 - dagamer34 - Sun Aug 22, 2004 1:26 am
DekuTree64 wrote: |
Just give me a little more time. After replying to your post earler, I decided to write up a little article series on sound system creation, and I have the first issue just about done. Since so many people will likely be tackling it for this compo, and I won't be able to resist answering all the questions, I may as well do it all in one go and have a nice reference for everyone later.
Although the first issue doesn't tackle resampling, so I guess I'll give a quick hint now: Use a fixed point position and increment, so you can play them at different speeds. Then add them together and divide by 2 to prevent overflow and you have the basics of a mixer. |
I look forward to your article. :)
_________________
Little kids and Playstation 2's don't mix. :(
#25416 - ProblemBaby - Sun Aug 22, 2004 3:21 pm
I got it to sound good in both no$gba and VBA however on real hardware I got some noise I think it is my scheme that is wrong it goes something like this:
Main Loop:
UpdateSound
VBlankIntr
DoOtherStuff
goto Main Loop
UpdateSound:
if Buffer1 is playing write new data to Buffer2
if Buffer2 is playing write new data to Buffer1
StopDMA
if Buffer1 is playing then change SAD to Buffer2
if Buffer2 is playing then change SAD to Buffer1
StartDMA
IS it something that I should change, you think?
#25424 - DekuTree64 - Sun Aug 22, 2004 6:24 pm
Hmm, sounds like you're doing things in the wrong order. The buffer swap should be done first thing in your VBlank interrupt, so the time between swaps is always exactly the same. It's usually best to keep the swap and data writing in seperate functions, since the swap is very time-critical but doesn't take very long, and the data writing is not time critical, but takes a long time to do. You can leave the data writing where it is, just the swap needs to be moved.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku