
	.include	"sound_mix.i"
	
	.section    	.iwram,"ax"
	.global		mix_chanels
	.align		4

mix_chanels:

	stmfd	sp!,{lr}			
	
	mov	r0,#0
	
	ldr	r6,[r9,#INSTR_LOOPEND]		@loopend1
	ldr	r7,[r9,#INSTR_LOOPSTART]		@loopstart1
	ldr	r8,[r9,#INSTR_POS]		@pos1
	
	cmp	r6,r7				@loopend1 = loopstart1
	bne	chanel1noPause
	cmp	r6,r8				@loopend1 = pos1
	moveq	r0,#0b01				@Chanel1 ist in Pause Modus
	moveq	r9,r10				@andere Kanal ist Master
	
chanel1noPause:	
	
	ldr	r6,[r10,#INSTR_LOOPEND]		@loopend1
	ldr	r7,[r10,#INSTR_LOOPSTART]	@loopstart1
	ldr	r8,[r10,#INSTR_POS]		@pos1
	
	cmp	r6,r7				@loopend1 = loopstart1
	bne	chanel2noPause
	cmp	r6,r8				@loopend1 = pos1
	orreq	r0,r0,#0b10			@Chanel1 ist in Pause Modus
	
chanel2noPause:	
	
	
	ldr r2,=mix_chanels_tbl
	ldr	r2,[r2,r0,lsl #2]
	mov	lr,pc
	bx	r2	
	
	ldmfd	sp!,{lr}
	bx	lr

	
mix_chanels_tbl:		.long	mix_2to1		@beide auf nicht pause -> 2 zu 1
			.long	mix_1to1		@einer auf nicht pause -> 1 zu 1
			.long	mix_1to1		@einer auf nicht pause -> 1 zu 1
			.long	mix_0to1		@beide auf pause       -> 0 zu 1

@***********************************************************:
@*:
@*: mixing 2 buffers to 1 
@*:
@*: r1  = output puffer
@*:
@*: r9  = instrumenStruktur1
@*: r10 = instrumenStruktur2
@*:

mix_2to1:

	stmfd	sp!,{r9,r10,lr}			@sampleX1 und sampleX2 auf stack

	ldr r0,=stacksave			@save sp
	str	sp,[r0]
	
	@****
			
	ldr	r6,[r9,#INSTR_LOOPEND]		@loopend1	
	ldr	r4,[r9,#INSTR_POS]		@pos1
	ldr	r5,[r9,#INSTR_FREQSTEP]		@freqstep1
	ldr	sp,[r9,#INSTR_VOLUME]		@vol1
	ldr	r0,[r9,#INSTR_SAMPLE]		@source1
	
	ldr	r12,[r10,#INSTR_LOOPEND]		@loopend2	
	ldr	r8,[r10,#INSTR_POS]		@pos2
	ldr	r11,[r10,#INSTR_FREQSTEP]	@freqstep2
	ldr	lr,[r10,#INSTR_VOLUME]		@vol2
	ldr	r7,[r10,#INSTR_SAMPLE]		@source2
	
	ldr	r9,[r9,#INSTR_LOOPSTART] 	@spos1
	ldr	r10,[r10,#INSTR_LOOPSTART] 	@spos2
	
	@**** get and mul mastervlume
	
	ldr r2,=sampleXAll
	ldr	r2,[r2,#MASTER_VOLUME]		@Master Volume
	
	mul	sp,sp,r2			@*vol1
	mul	lr,lr,r2			@*vol2
	
	mov	sp,sp ,lsr #9
	mov	lr,lr ,lsr #9
	
	@**** shrink registers
	
	orr	r5,r11,r5 ,lsl #16		@freqstep1:freqstep2
	orr	sp,lr,sp ,lsl #16			@vol1:vol2	
	
	ldr	lr,=SAMPLE_BUFFER_LENGTH	
	
	@****

mixloop:

	@r0 = source1
	@r1 = dest
	@r2 = XXXX
	@r3 = XXXX
	@r4 = pos1
	@r5 = freqstep1:freqstep2
	@r6 = length1
	
	@r7  = source2
	@r8  = pos2
	@r9  = s1adr
	@r10 = s2adr
	@r11 = XXXX
	@r12 = length2
	@lr  = count
	@sp  = vol1:vol2

	@**** get data of Source1&2
	
	mov	r3,r4  ,lsr #11			@pos
	mov	r11,r8 ,lsr #11			@pos
	
	ldrsb	r2,[r3,r0]			@r2=[pos+adr]
	ldrsb	r3,[r11,r7]			@r3=[pos+adr]

	@**** inc pos and check loops for Source 1

	add	r4,r4,r5 ,lsr #16			@pos + freqstep
	cmp	r4,r6 				@length?
	movge	r4,r9			 	@ja-> pos=spos
	
	@**** inc pos and check loops for Source 2
	
	mov	r11,r5 ,lsl #16
	add	r8,r8,r11 ,lsr #16		@pos + freqstep
	cmp	r8,r12				@epos?
	movge	r8,r10			 	@ja-> pos=spos
		
	@**** mix + volume
	
	mov	r11,sp ,lsr #16		@vol1
	mul	r2,r2,r11		@source1*vol1
	
	bic	r11,sp,r11 ,lsl #16	@vol2 = vol1:vol2 AND NOT vol1<<16
	mla	r3,r3,r11,r2		@source2*vol2+source1*vol1
	
	mov	r3,r3 ,asr #10		@9 Vol * 2 Chanels

	@**** Boost Schutz

	@cmp	r3,#127
	@movge	r3,#127
	@cmn	r3,#128
	@mvnle	r3,#128-1
	
	@**** Schreibe
	
	strb	r3,[r1],#1

	subs	lr,lr,#1
	bne	mixloop						

	@**** get old stack		
			
	ldr r0,=stacksave
	ldr	sp,[r0]	
	
	ldmfd	sp!,{r9,r10}		@sampleX1 & ampleX2
			
	str	r8,[r10,#INSTR_POS]	@save pos		
	str	r4,[r9,#INSTR_POS]	@save pos		
		
	@****	
		
	ldmfd	sp!,{lr}			@ldmfd	sp!,{pc} gibt bei batgba falschen sp ?!
	bx	lr


@***********************************************************:
@*:
@*: mixing 1 buffers to 1 (halbe Lautstärke)
@*:
@*: r1  = output puffer
@*:
@*: r9  = instrumenStruktur1

mix_1to1:

	stmfd	sp!,{lr}			@sampleX1 und sampleX2 auf stack
	
	@****
			
	ldr	r6,[r9,#INSTR_LOOPEND]		@loopend1	
	ldr	r4,[r9,#INSTR_POS]		@pos1
	ldr	r5,[r9,#INSTR_FREQSTEP]		@freqstep1
	ldr	r8,[r9,#INSTR_VOLUME]		@vol1
	ldr	r0,[r9,#INSTR_SAMPLE]		@source1
	ldr	r7,[r9,#INSTR_LOOPSTART] 	@spos1
	
	@**** get and mul mastervlume
	
	ldr r2,=sampleXAll
	ldr	r2,[r2,#MASTER_VOLUME]		@Master Volume
	
	mul	r8,r8,r2			@*vol1
	mov	r8,r8 ,lsr #9			@/512
	
	@**** shrink registers
		
	ldr	lr,=SAMPLE_BUFFER_LENGTH/4	
	
	@**** Lädt 4 Bytes

mix1loop:

	
	mov	r3,r4  ,lsr #11			@pos
	ldrsb	r2,[r3,r0]			@r2=[pos+adr]
	
	add	r4,r4,r5 			@pos + freqstep
	cmp	r4,r6 				@length?
	movge	r4,r7			 	@ja-> pos=spos
	
	mov	r3,r4  ,lsr #11			@pos
	ldrsb	r10,[r3,r0]			@r2=[pos+adr]
	
	add	r4,r4,r5 			@pos + freqstep
	cmp	r4,r6 				@length?
	movge	r4,r7			 	@ja-> pos=spos
	
	mov	r3,r4  ,lsr #11			@pos
	ldrsb	r11,[r3,r0]			@r2=[pos+adr]
	
	add	r4,r4,r5 			@pos + freqstep
	cmp	r4,r6 				@length?
	movge	r4,r7			 	@ja-> pos=spos
	
	mov	r3,r4  ,lsr #11			@pos
	ldrsb	r12,[r3,r0]			@r2=[pos+adr]
	
	add	r4,r4,r5 			@pos + freqstep
	cmp	r4,r6 				@length?
	movge	r4,r7			 	@ja-> pos=spos
	
	mul	r3,r2,r8			@sourcex*vol1
	mul	r10,r10,r8		
	mul	r11,r11,r8	
	mul	r12,r12,r8		
	
	mov	r3,r3 ,asr #10			@/9Vol /2		
	mov	r10,r10 ,asr #10			
	mov	r11,r11 ,asr #10			
	mov	r12,r12 ,asr #10			
	
	@r12:r11:r10:r3
	
	and	r3,r3,#0xff
	and	r10,r10,#0xff
	and	r11,r11,#0xff
	
	orr	r3,r3,r12 ,lsl #24	@r12:XX:XX:r3
	orr	r3,r3,r11 ,lsl #16	
	orr	r3,r3,r10 ,lsl #8
		
	str	r3,[r1],#4

	subs	lr,lr,#1
	bne	mix1loop						

	@**** get old stack		
							
	str	r4,[r9,#INSTR_POS]	@save pos		
		
	@****	
		
	ldmfd	sp!,{lr}			@ldmfd	sp!,{pc} gibt bei batgba falschen sp ?!
	bx	lr
	
@***********************************************************:
@*:
@*: mixing 0 buffers to 1 (lösche buffer)
@*:
@*: r1  = output puffer
@*:

mix_0to1:

	ldr	r0,=SAMPLE_BUFFER_LENGTH/16

	mov	r2,#0
	mov	r3,#0	
	mov	r4,#0
	mov	r5,#0
	mov	r6,#0
	mov	r7,#0	
	mov	r8,#0
	mov	r9,#0
	
	mov	r10,r0 ,lsr #1		@/2
	sub	r11,r0,r10 ,lsl #1	@rest
	
mix0loop:

	stmia	r1!,{r2-r9}		@lösche 32Byte
	subs	r10,r10,#1
	bne	mix0loop
	
	cmp	r11,#1
	stmeqia	r1!,{r2-r5}		@wenn 16ner Rest -> löschen
			
	bx	lr

	.end
	
	
	