#31870 - mr_square - Wed Dec 15, 2004 4:12 pm
I'm getting clicking noises when I turn on the AAS audio mixer - it seems to be largely when AAS is doing a lot of DMA transfers.
Any way to fix this? Thanks.
#31883 - tepples - Wed Dec 15, 2004 6:14 pm
I think you need to 1. use only DMA channel 3 for copies, and 2. use a single 'stmia' instruction to write to all 3 DMA registers at once, as AAS_DoDMA3() does.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#31904 - jd - Wed Dec 15, 2004 8:02 pm
Clicking is usually caused by the AAS interrupt not being serviced quickly enough. This usually happens if you're using other CPU-intensive interrupts or doing big DMA transfers. Fixing the former involves using the interrupt handling method shown in AASExample2. Fixing the later means either splitting the DMA transfers into smaller chunks or doing them with the CPU instead.
#31987 - mr_square - Thu Dec 16, 2004 5:08 pm
Cool - thanks. Most of my sprites are 64x64, so its probably copying in that data thats causing it.
#33380 - mr_square - Sun Jan 02, 2005 7:32 pm
For anyone thats interested - simply dropping the mixing frequency to 16khz in AAS_SetConfig sorted out all the clicking.
#33405 - jd - Mon Jan 03, 2005 1:16 am
mr_square wrote: |
For anyone thats interested - simply dropping the mixing frequency to 16khz in AAS_SetConfig sorted out all the clicking. |
Yes, that would make the processing the timer 1 interrupt slightly less time-critical which could be enough to stop the clicking, but I wouldn't recommend it as a general solution. If you do bigger DMA transfers at some point in the future then the clicking will return. A better solution would be to split the transfers up, use CPU transfers or make sure you only do DMA transfers when you know a timer 1 interrupt isn't imminent (i.e. after it has just happened).
#33417 - tepples - Mon Jan 03, 2005 4:17 am
Are they 64x64 pixels in 16 color (2048 bytes per cel), or are they 64x64 pixels in 256 color (4096 bytes per cel)? Where are you copying from, and if ROM, at what wait state? Perhaps I can help guide you about CPU cycle use.
This DMA conflict is one of the bugbears when using a mixing engine that synchronizes to an arbitrary timer rather than to vblank.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#33429 - jd - Mon Jan 03, 2005 7:57 am
tepples wrote: |
This DMA conflict is one of the bugbears when using a mixing engine that synchronizes to an arbitrary timer rather than to vblank. |
It is also a problem for mixers that synchronise to vblank if the DMA transfers aren't also synchonised to vblank - or if the transfer is big enough to take more than 1/60th second.
#33450 - tepples - Mon Jan 03, 2005 5:05 pm
jd wrote: |
It is also a problem for mixers that synchronise to vblank if the DMA transfers aren't also synchonised to vblank |
In a sprite engine, DMA transfers usually are synchronized to vblank: BIOS VblankIntrWait, then switch buffers, then update sprite cel VRAM and OAM. In fact, a lot of GBA programmers come from earlier systems where the VRAM was not dual-ported and could be written to only during vblank. In practice, it's a lot easier to structure a game loop around vblank than around timer 1.
Quote: |
or if the transfer is big enough to take more than 1/60th second. |
DMA from EWRAM takes 4 cycles per 2 bytes. This would fill the 96 KB VRAM in about 160 scanlines of CPU time, well within one frame's vblank and draw times. If you limit yourself to just sprite cels, it's possible to refill all of sprite cel VRAM within vblank time. Which big transfer were you talking about?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#33453 - jd - Mon Jan 03, 2005 6:13 pm
tepples wrote: |
In a sprite engine, DMA transfers usually are synchronized to vblank: BIOS VblankIntrWait, then switch buffers, then update sprite cel VRAM and OAM. In fact, a lot of GBA programmers come from earlier systems where the VRAM was not dual-ported and could be written to only during vblank. In practice, it's a lot easier to structure a game loop around vblank than around timer 1.
|
Yes, although if it were a 3d game you might not be syncing with vblank.
tepples wrote: |
DMA from EWRAM takes 4 cycles per 2 bytes. This would fill the 96 KB VRAM in about 160 scanlines of CPU time, well within one frame's vblank and draw times. If you limit yourself to just sprite cels, it's possible to refill all of sprite cel VRAM within vblank time. Which big transfer were you talking about? |
I wasn't thinking of a particular example, although a ROM transfer to fill EWRAM would take more than 1/60th sec - I can't think of a reason you'd need to do this, though.
#33573 - mr_square - Wed Jan 05, 2005 6:15 pm
tepples wrote: |
Are they 64x64 pixels in 16 color (2048 bytes per cel), or are they 64x64 pixels in 256 color (4096 bytes per cel)? Where are you copying from, and if ROM, at what wait state? Perhaps I can help guide you about CPU cycle use.
This DMA conflict is one of the bugbears when using a mixing engine that synchronizes to an arbitrary timer rather than to vblank. |
They're 256 color, which I'm really regretting now as they've gobbled up all my video memory, severely increased the amount of graphics I need to draw and, I assume, have caused some of these clicking problems. They're 'const' arrays (so stored in ROM, no?) and I think I'm copying them in at Vblank - once I switched to AAS I threw out all my old DMA code and just used AAS_DoDMA3, so whatever that defaults to.
I'd love to drop them down to 16 color, but sadly they're a bit too built into the code now, and I don't really have the time to sort it all out (I'm doing my game for a project, deadline in 2 months). Its the same with most of my code - I've learnt so much about the GBA compared to when I started that I'm finding faults with pretty much everything now! :p
Also - jd, I think I've heard you say on a couple of occasions that optimised CPU transfers can be almost as fast as DMA - how so?
#33584 - tepples - Wed Jan 05, 2005 8:25 pm
There is a BIOS function that does such an "optimized CPU transfer", taking the same arguments as AAS_DoDMA3(), and it's called CpuFastSet(). GBATEK has more information.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.