#157777 - Ruben - Thu May 29, 2008 2:39 am
Hey guys. I recently finished a stereo mixer which I should be about to release but it takes a bit long to mix down each channel. I was wondering if there's any room for improvement?
These are the structs
The mono code for the mixer is really fast but after I added those 3 instructions for the right channel, it's slowed down quite a lot. Thanks a lot guys.[/code]
EDIT: Fixed up the misaligned text
Code: |
.section .iwram, "ax", %progbits
.align .global S3MTmp S3MTmp: .space 304*2*16/8 .size S3MTmp, .-S3MTmp .align @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .section .iwram, "ax", %progbits .align .arm .global S3MMixdown .extern S3MBuffer .extern S3MVrs S3MMixdown: .LStart: stmfd sp!, {r4-r11, r14} @ save used registers .LPreClearLoop: ldr r1, =S3MTmp @ r1 = S3MBuffer mov r2, r0 @ r2 = samples to mix mov r3, #0x00 @ r3 = 0 mov r4, #0x00 @ r4 = 0 mov r5, #0x00 @ r5 = 0 mov r6, #0x00 @ r6 = 0 .LClearLoop: stmia r1!, {r3-r6} @ store 4 samples subs r2, r2, #0x04 @ subtract those 4 samples bhi .LClearLoop @ if positive, then keep clearing @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .LPreChannelLoop: mov r1, #0x20 @ r1 = channel count (32) ldr r2, =S3MVrs @ \ add r2, r2, #0x28 @ r2 = pointer to channels .LChannelLoop: ldr r3, [r2] @ r3 = cnt tst r3, #0x01 @ \ beq .LChannelLoopEnd @ if(not active) dont do this channel .LPreSampleLoop: mov r4, r0 @ r4 = samples to mix ldmib r2, {r5-r8} @ r5 = source @ r6 = position @ r7 = increment @ r8 = length ldr r9, =S3MTmp @ r9 = S3MTmp ldr r11, =S3MVrs @ \ ldrb r12, [r11, #0x15] @ r10 = master volume mov r10, r3, asr #0x02 and r10, r10, #0x7F mul r10, r12, r10 @ r10 = channel vol (left) * master vol mov r10, r10, asr #0x04 @ r10 = final volume mov r11, r3, asr #0x09 and r11, r11, #0x7F mul r11, r12, r11 @ r11 = channel vol (right) * master vol mov r11, r11, asr #0x04 @ r11 = final volume .LSampleLoop: @ do left channel add r12, r5, r6, lsr #0x0C @ r12 = position in ROM ldrsb r12, [r12] @ r12 = sample add r6, r6, r7 @ pos += inc add r14, r5, r6, lsr #0x0C @ r14 = position in ROM ldrsb r14, [r14] @ r14 = sample add r6, r6, r7 @ pos += inc add r12, r12, r14, lsl #0x10 @ r12 = 2 samples ldr r14, [r9] @ r14 = mixed data mla r14, r10, r12, r14 @ r14 = final data str r14, [r9], #0x04 @ store mixed data and increment @ do right channel ldr r14, [r9] @ r14 = mixed data mla r14, r11, r12, r14 @ r11 = final data str r14, [r9], #0x04 @ store mixed data and increment cmp r6, r8 @ \ bge .LSampleNoData @ if(pos >= length) do some stuff .LSampleLoopEnd: subs r4, r4, #0x02 @ \ bhi .LSampleLoop @ if(--samples left) keep looping .LChannelLoopEnd: str r3, [r2], #0x08 @ store cnt str r6, [r2], #0x10 @ store pos; channel++ subs r1, r1, #0x01 @ \ bne .LChannelLoop @ if(--channels left != 0) loop again b .LPreDownsampleLoop @ skip the end of sample handler .LSampleNoData: tst r3, #0x02 @ test for loop flag ldrne r6, [r2, #0x14] @ if(looping) get loop begin position bne .LSampleLoopEnd @ keep looping bic r3, r3, #0x01 @ clear the active flag b .LChannelLoopEnd @ stop looping @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .LPreDownsampleLoop: ldr r1, =S3MTmp @ r1 = S3MTmp ldr r2, =S3MVrs @ r2 = S3MVrs ldr r3, [r2, #0x04]! @ r3 = left buffer location add r4, r3, #0x260 @ r4 = right buffer location add r5, r3, r0 @ r4 = buffer location + samples mixed str r5, [r2] @ store this location .LDownsampleLoop: ldrsh r5, [r1], #0x02 @ get mixed samples (left) movs r5, r5, asr #0x07 cmnmi r5, #0x80 mvnlt r5, #0x7F cmppl r5, #0x7F movgt r5, #0x7F strb r5, [r3], #0x01 @ store ldrsh r5, [r1], #0x02 @ get mixed samples (left) movs r5, r5, asr #0x07 cmnmi r5, #0x80 mvnlt r5, #0x7F cmppl r5, #0x7F movgt r5, #0x7F strb r5, [r3], #0x01 @ store ldrsh r5, [r1], #0x02 @ get mixed samples (right) movs r5, r5, asr #0x07 cmnmi r5, #0x80 mvnlt r5, #0x7F cmppl r5, #0x7F movgt r5, #0x7F strb r5, [r4], #0x01 @ store ldrsh r5, [r1], #0x02 @ get mixed samples (right) movs r5, r5, asr #0x07 cmnmi r5, #0x80 mvnlt r5, #0x7F cmppl r5, #0x7F movgt r5, #0x7F strb r5, [r4], #0x01 @ store subs r0, r0, #0x02 bcs .LDownsampleLoop .LEnd: ldmfd sp!, {r4-r11, r14} @ restore used registers bx lr @ return |
These are the structs
Code: |
typedef struct tChn {
u32 cs; //channel status (bit0: on. bit1: loop. bit2-8: vol left. bit9-F: vol right) s8* wp; //wave pointer u32 cp; //channel position (20.12 fixed point) u32 ci; //channel increment (20.12 fixed point) u32 cl; //channel length (20.12 fixed point) u32 lb; //loop begin (20.12 fixed point) } tChn; typedef struct tSndArea { //mixer stuff s8 *bb; //base buffer (+0) s8 *mb; //mix buffer (current) (+4) u32 fr; //mix frequency (+8) u32 st; //samples til tick (20.12FP) (+C) u32 sp; //samples per tick (20.12FP) (+10) u8 ab; //active buffer (+14) u8 mv; //master volume (default 15) (+15.. COINCIDENCE?! lol) u16 sc; //sound control (+16) //player stuff tS3M *pm; //pointer to module (+18) u8 *nb; //next byte (+1C) u8 mp; //module speed (+20) u8 mt; //module tempo (+21) u8 mc; //mixer count/tick/tap (+22) u8 cr; //current row (+23) u8 co; //current order (+24) u8 oc; //order count (+25) tChn pc[32]; //player channels (+26) u8 pd; //pattern delays left u32 ef; //effect flags u8 ep[32]; //effect paramaters } tSndArea; |
The mono code for the mixer is really fast but after I added those 3 instructions for the right channel, it's slowed down quite a lot. Thanks a lot guys.[/code]
EDIT: Fixed up the misaligned text