#171736 - Ruben - Fri Dec 18, 2009 10:42 am
Hi.
So I decided to see if you guys have any optimization ideas for my GBA mixer, which I intend to also port to the DS for 30 channel output. So... here's the latest code. (It's a bit messy due to tabs and quite long >_<')
Any tips, specially on the hotspot (mixing)?
So I decided to see if you guys have any optimization ideas for my GBA mixer, which I intend to also port to the DS for 30 channel output. So... here's the latest code. (It's a bit messy due to tabs and quite long >_<')
Code: |
/**********************************************/
#include "sasInternal.inc" /**********************************************/ .global sasMain /**********************************************/ .text .align .thumb .thumb_func sasMain: ldr r0, =sasVar ldrb r1, [r0] lsr r1, #0x01 @ if(mixer == off) bcc 2f @ return push {lr} ldr r0, =sasUpdate bl 1f @ update songs pop {r0} mov lr, r0 ldr r0, =sasARM @ could probably incorporate @ into sasUpdate but meh. 1: bx r0 2: bx lr .align .size sasMain, .-sasMain /**********************************************/ .section .iwram, "ax", %progbits .align .arm sasARM: stmfd sp!, {r4-r11,lr} @ clear 16-bit interleaved stereo mixing buffer ldr r0, =.LMixBuffer ldr r1, =SAS_BUFSIZE / 8 mov r2, #0x00 mov r3, #0x00 mov r4, #0x00 mov r5, #0x00 mov r6, #0x00 mov r7, #0x00 mov r8, #0x00 mov r9, #0x00 1: subs r1, r1, #0x01 stmhsia r0!, {r2-r9} bne 1b ldr ip, =sasVar ldmia ip, {r0-r2} @ {xxPPVVxx,LLLLxxxx,RRRRRRRR} mov r0, r0, lsr #0x08 @ 00xxPPVV bic r0, r0, #0xFF0000 @ 0000PPVV orr r0, r0, r0, lsl #0x08 @ 00PPxxVV bic r0, r0, #0xFF00 @ 00PP00VV subs r0, r0, #0x010000 @ if(--pp < 0) addmi r0, r0, #0x010000 @ pp = 0 mov r1, r1, lsr #0x10 @ 0000LLLL ldr r3, =.LMixBuffer ldr r4, =sasChan /******************************\ * r0-L16 * Volume * * r0-H16 * Polyphony * * r1-X32 * Buffer length * * r2-X32 * Reciprocal * * r3-X32 * Mixing buffer * * r4-X32 * Channel * \******************************/ .LOLChan: ldr r5, [r4], #SAS_CHANSIZE tst r5, #sasOn + sasNoteOn beq .LOLChanContinue @ if(channel == off || no note on) continue stmfd sp!, {r0-r4} sub r4, r4, #SAS_CHANSIZE .LILChanEnv: mov r6, r5, lsr #0x04 and r6, r6, #0x0F ldr r7, [r4, #0x18] @ env {a,d,s,r}, 8-bit mov r9, #0xFF and r8, r9, r5, lsr #0x08 @ env_val bic r5, r5, r8, lsl #0x08 @ env_val = 0 tst r5, #sasNoteOn bne .LILChanNoteOn tst r5, #sasNoteOff bne .LILChanNoteOff .LILChanEnv000: cmp r6, #sasAttack @ if(env_state != attack) bne .LILChanEnv001 @ continue and ip, r9, r7 add r8, r8, ip @ env += env_val cmp r8, #0xFF ble .LILChanEnvEnd @ if(env <= 255) goto mix tst r7, #0xFF00 @ if(env[decay]) { movne r8, #0xFF @ env_val = 255, movne r6, #sasDecay @ env_state = decay andeq r8, r9, r7, lsr #0x10 @ } else { moveq r6, #sasSustain @ env_val = sustain_val, env_state = sustain b .LILChanEnvEnd @ } goto mix .LILChanEnv001: cmp r6, #sasDecay bne .LILChanEnv002 and ip, r9, r7, lsr #0x08 subs r8, r8, ip @ if(env_val -= env[decay] <= 0) ble .LIllegalChanState @ chan->stop() and ip, r9, r7, lsr #0x10 cmp r8, ip @ if(env_val <= env[sustain]) movle r6, #sasSustain @ env_state = sustain b .LILChanEnvEnd .LILChanEnv002: cmp r6, #sasSustain bne .LILChanEnv003 and r8, r9, r7, lsr #0x10 @ env = env[sustain] b .LILChanEnvEnd .LILChanEnv003: cmp r6, #sasRelease bne .LIllegalChanState subs r8, r8, r7, lsr #0x18 @ if(env_val -= env[release] <= 0) bgt .LILChanEnvEnd ble .LIllegalChanState @ chan->stop() .LILChanNoteOn: ldr r11, [ r4, #0x20] @ &wave ldr r12, [r11, #0x0C] @ wave->length #if SAS_MIXMODE == SAS_MIXMODE_NN rsb r14, r12, #0x00 @ -length (negated for mixing trick) str r14, [ r4, #0x10] #else str r12, [ r4, #0x10] #endif add r14, r12, r11 @ &wave + length add r14, r14, #0x10 @ wave->data + length str r14, [ r4, #0x04] ldrb r14, [r11] ands r14, r14, #sasLooped ldrne r14, [r11, #0x08] @ wave->loop rsbne r14, r14, r12 @ store loop size str r14, [ r4, #0x14] @ else store 0 mov r14, #0x00 str r14, [ r4, #0x08] @ remainder = 0 bic r5, r5, #0xFF @ env_stat = 0, stat = 0 orr r5, r5, #sasOn @ stat = on tst r7, #0xFF movne r6, #sasAttack movne r8, #0x00 bne .LILChanEnv000 tst r7, #0xFF00 movne r6, #sasDecay movne r8, #0xFF bne .LILChanEnv001 tst r7, #0xFF0000 movne r6, #sasSustain bne .LILChanEnv002 tst r7, #0xFF000000 movne r6, #sasRelease movne r8, #0xFF bne .LILChanEnv003 beq .LIllegalChanState .LILChanNoteOff: tst r7, #0xFF000000 movne r6, #sasRelease bne .LILChanEnv003 beq .LIllegalChanState .LILChanEnvEnd: orr r5, r5, r8, lsl #0x08 @ env_val = new env_val bic r5, r5, #0xF0+sasNoteOn+sasNoteOff @ env_stat = 0, clear note on/off orr r5, r5, r6, lsl #0x04 @ env_stat = new env_stat strh r5, [r4] mov ip, r5, lsr #0x18 @ panning mov r5, r5, lsr #0x10 and r5, r5, #0xFF @ volume mul r5, r8, r5 @ volume * env and r0, r0, #0xFF mul r6, r5, r0 @ volume * env * mvol movs r5, r6, lsr #0x08 + 7 beq .LIllegalChanState rsb r6, ip, #0x7F mul r6, r5, r6 @ vol * (127 - pan) mov r6, r6, lsr #0x07 mul r5, ip, r5 @ vol * ( 0 + pan) mov r5, r5, lsr #0x07 orr r5, r5, r6, lsl #0x10 @ lvol + rvol<<16 ldmib r4, {r7-r11} umull r2, r9, r9, r2 #if SAS_MIXMODE == SAS_MIXMODE_NN cmp r11, #0x00 beq .LILChanMixOS .macro MixFL or ldrsb r14, [r7, r10] mla \or, r5, r14, \or @ smp*vols + out adds r8, r8, r2 @ sub += subinc adcs r10, r10, r9 @ adc to true position subpl r10, r10, r11 @ if <0 loop .endm .macro MixOS or ldrsb r14, [r7, r10] mla \or, r5, r14, \or @ smp*vols + out adds r8, r8, r2 adcs r10, r10, r9 bpl .LOutOfData @ kill on finish .endm .LILChanMixFL: ldmia r3 , {r0,r4,r6,ip} MixFL r0 MixFL r4 MixFL r6 MixFL ip stmia r3!, {r0,r4,r6,ip} subs r1, r1, #0x04 bne .LILChanMixFL beq .LILChanMixEnd .LILChanMixOS: ldmia r3 , {r0,r4,r6,ip} MixOS r0 MixOS r4 MixOS r6 MixOS ip stmia r3!, {r0,r4,r6,ip} subs r1, r1, #0x04 bne .LILChanMixOS #else str r11, .LoopSize @ store loop length add r11, r7, #0x01 @ src + 1 (for interpolation) mov r2, r2, lsr #0x20-23 @ cfreq<<23/sfreq orr r2, r2, r9, lsl #0x17 @ (add integer portion << 23) .macro Mix or ldrsb r14, [ r7, -r10] @ s0 ldrsb r9, [r11, -r10] @ s1 sub r9, r9, r14 @ s1-s0 mul r9, r8, r9 @ subpos(s1-s0) add r14, r14, r9, asr #0x17 @ f(s1-s0) ~= s0.sub mla \or, r5, r14, \or @ smp*vols + out add r8, r8, r2 @ pos += inc subs r10, r10, r8, lsr #0x17 @ smpleft -= pos >> 23 bic r8, r8, #0x3F800000 @ smpleft -= integer blls .LNoDat @ no data left .endm .LILChanMix: ldmia r3 , {r0,r4,r6,ip} Mix r0 Mix r4 Mix r6 Mix ip stmia r3!, {r0,r4,r6,ip} subs r1, r1, #0x04 bne .LILChanMix #endif .LILChanMixEnd: ldr r0, [sp, #0x04*4] str r8, [r0, #0x08-SAS_CHANSIZE] str sl, [r0, #0x10-SAS_CHANSIZE] .LILChanDone: ldmfd sp!, {r0-r4} .LOLChanContinue: subs r0, r0, #0x010000 bhs .LOLChan /******************************\ * r0-X32 * Destination * * r1-X32 * Buffer length * * r2-X32 * Mask 00FF00FF * * r3-X32 * Mixing buffer * \******************************/ .LDownsample: ldr r0, =sasBuffer ldr r2, =sasVar ldrb r2, [r2, #0x03] cmp r2, #0x02 @ mix to buffer 2? addeq r0, r0, r1 @ yes. mov r2, #0xFF orr r2, r2, r2, lsl #0x10 1: ldmia r3!, {r4-r7} and r4, r2, r4, lsr #0x08 and r5, r2, r5, lsr #0x08 orr r4, r4, r5, lsl #0x08 and r6, r2, r6, lsr #0x08 and r7, r2, r7, lsr #0x08 orr r6, r6, r7, lsl #0x08 eor r6, r6, r4, lsr #0x10 eor r4, r4, r6, lsl #0x10 eor r6, r6, r4, lsr #0x10 str r6, [r0, #SAS_BUFSIZE*2] str r4, [r0], #0x04 subs r1, r1, #0x04 bne 1b .LExit: ldmfd sp!, {r4-r11,lr} bx lr .LIllegalChanState: mov r5, #0x00 strb r5, [r4] b .LILChanDone #if SAS_MIXMODE == SAS_MIXMODE_LI .LoopSize: .word 0 .LNoDat: ldr r9, .LoopSize adds sl, sl, r9 movgt pc, lr ldr r4, [sp, #0x04*4] str r9, [r4, #-SAS_CHANSIZE] b .LILChanDone #endif #if SAS_MIXMODE == SAS_MIXMODE_NN .LOutOfData: ldr r4, [sp, #0x04*4] strb r11, [r4, #-SAS_CHANSIZE] b .LILChanDone #endif .LMixBuffer: .space SAS_BUFSIZE * 4 .align .size sasARM, .-sasARM /**********************************************\ * EOF * \**********************************************/ |
Any tips, specially on the hotspot (mixing)?