Wednesday, June 10, 2009

Oops, yeah, sound mixing tricks

Hehehe, so yeah, I got a bit behind... Anyway...

So as we know, sound is mixed with addition, yeah? Yeah. So the most simple loop would be something like...

int Divdn = Channel.Freq<<24 / MasterFreq;
int Delta = Channel.Delta;
s8 *Src0 = Channel.Source;
s16 *Dst0 = LeftChannel; //Interleaved data as RRRRLLLL
s16 *Dst1 = Dst1+1;
do {
*Dst0++ += *Src0*LeftVol / 128;
*Dst1++ += *Src0*RightVol / 128;

Delta += Divdn;
if(Delta>>24) {
Src0 += Delta>>24;
Delta &= ~0xFF000000;
if(Src0 >= Channel.End) Src0 = Channel.Loop;
}
} while(--Smp > 0);

Ok, sure, it's simple and it works, but not as fast as it can be. So what do we do? We combine the left/right multiplications and stores into a single s32 pointer like this...


int Divdn = Channel.Freq<<24 / MasterFreq;
int Delta = Channel.Delta;
s8 *Src0 = Channel.Source;
s32 *Dst0 = LeftChannel;
u32 Volu = ((RightVol+1)<<16) + LeftVol+1; //Could be 0 that stuffs up the next trick
do {
s32 Value = Volu * *Src0;
if(Value > 0) Value &= ~0x7F0000; //Clear bits
if(Value < 0) Value |= 0x7F0000; //Fill sign
//A smart enough compiler should optimize it to...
//muls value, volue, srcdat
//bicgt value, value, #0x7F0000
//orrlt value, value, #0x7F0000

*Dst0++ += Value / 128;

Delta += Divdn;
if(Delta>>24) {
Src0 += Delta>>24;
Delta &= ~0xFF000000;
if(Src0 >= Channel.End) Src0 = Channel.Loop;
}
} while(--Smp > 0);

So what started off as 2 multiplications, 2 adds and 2 loads/stores, has been transformed to 1 multiplication, 2 sign checks, 1 add, 1 load/store.

The next optimization is just optimized unrolling with LDMIA/STMIA pairs but that's about it.. Another optimization would probably be to have different loops for looped samples/1 shot samples. But there's not much optimization after that. Unless you want to do .12 fixed-point rather than .24 and loading for every sample, regardless of if it changed. If you really want to get the best out of it, you could go to ARM ASM, which I've done and have managed to speed up things radically.

No comments:

Post a Comment