Search the web
Sign In
New User? Sign Up
gbadev
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Want your group to be featured on the Yahoo! Groups website? Add a group photo to Flickr.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
Can someone help me with DMA DirectSound?   Message List  
Reply | Forward Message #13216 of 15019 |
Re: Can someone help me with DMA DirectSound?

--- In gbadev@y..., "David Clear" <davidc@a...> wrote:
>
> I have an application where I have music source data that is
> converted to DirectSound samples on the fly (i.e. the entire
> tune is too big to be decompressed into one large sample).

In other words, you're working on a music player based
on ADPCM or sub-band audio coding, right? Or is your
"compression" really just a MIDI or MOD player? Both
approaches to music will typically use a double buffer.

> The approach I am considering is a simple double-buffer. Play one
> buffer whilst decoding the next music segment into the other.

That's how most mixers and decompressors work.

> From some tutorials on the web, I have managed to play a single
> buffer, however, I am not sure what to do to flip over to the
> second buffer.
>
> This is what I am doing:
>
> 1. Setup Timer0 at 44.1kHz to play the sample.

I wouldn't suggest 44.1 kHz because it doesn't divide evenly
into the length of a frame.

Previously, I gave the conditions for a good sample buffer size:
* the size should be a factor of 280896 (the time in cycles of
one frame), and
* the size should be a multiple of 4 (the width of the FIFO).

I generally use a pair of 304-sample buffers, which gives a period
of 924 cycles per sample and a sample frequency of 18157 Hz. If I
could spare the CPU time, I could double that to 608 samples and
36314 Hz.

> 2. Setup Timer1 to cascade, counting N samples and then
> interrupting.

Turning on more than one periodic interrupt (vblank and timers)
complicates concurrent real-time programming significantly. To
simplify things, I switch buffers inside my vblank interrupt,
which is why I make my buffers the same length as a frame and
limit my sample rates.

> 3. Set DMA1 from the first soundbuffer.
> 4. Enable Timer0.
>
> Now I'll get an interrupt from Timer1 after N samples.
>
> Q. What do I have to do to seamlessly move over to
> the second buffer?
> - I think I have to:
> 1. Disable Timer0.
> 2. Disable DMA1.
> 3. Reset DMA1 to new source buffer.
> 4. Reenable DMA1.
> 5. Reenable Timer0.

You don't need to do steps 1 and 5, but you do need to wait
a few cycles after step 2 because a write to the DMA channel's
control register needs a couple cycles to take effect.

My mixer code uses the following function to start a buffer going
or to switch buffers.

void dsound_switch_buffers(const signed char *src)
{
DMA[1].control = 0;

/* no-op to let DMA registers catch up */
asm volatile ("eor r0, r0; eor r0, r0" ::: "r0");

DMA[1].src = src; //dma1 source
DMA[1].dst = (void *)0x040000a0; //write to FIFO A address
DMA[1].count = 1;
DMA[1].control = DMA_DSTUNCH | DMA_SRCINC | DMA_REPEAT | DMA_U32 |
DMA_SPECIAL | DMA_ENABLE;
/* DMA_SPECIAL is the special trigger mode for each channel.
For channel 1, it's triggered by the FIFO. If you're using
"standard" headers, it'll probably be called something else. */
}

> This does not work on VisualBoyAdvance (although I have not
> tried on my hardware yet).

The mixer code from Tetanus On Drugs M2 is in 100% commented,
optimized C[1] and works on at least the GBA, VisualBoyAdvance,
Boycott Advance, and BatGBA. Look at that if you're confused
as to how to get a double buffer working.
http://www.pineight.com/gba/

[1] Some consider hand-tweaking C code a bad idea because
different compilers with different switch settings will
compile a given piece of code drastically differently.
However, if your optimized C uses very simple instructions,
the compiler will generate code quite a bit more predictably.
To see how, read ARM application note 34:
http://www.arm.com/support/567GCF/$File/DAI0034A_efficient-c.pdf

--
Damian





Tue Nov 5, 2002 1:29 am

yerricde
Offline Offline
Send Email Send Email

Forward
Message #13216 of 15019 |
Expand Messages Author Sort by Date

Hi. I have an application where I have music source data that is converted to DirectSound samples on the fly (i.e. the entire tune is too big to be...
David Clear
davidclear
Online Now Send Email
Nov 4, 2002
10:17 pm

... In other words, you're working on a music player based on ADPCM or sub-band audio coding, right? Or is your "compression" really just a MIDI or MOD...
yerricde
Offline Send Email
Nov 5, 2002
9:29 am
Advanced

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help