Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 377 → Rev 378

/kernel/trunk/drivers/mixer.asm
13,96 → 13,67
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
 
 
align 4
 
mix_list rq 32
 
align 4
proc new_mix stdcall, output:dword
locals
mixCounter dd ?
mixIndex dd ?
streamIndex dd ?
inputCount dd ?
main_count dd ?
blockCount dd ?
mix_out dd ?
main_count rd 1
fpu_state rb 528 ;512+16
endl
 
mov [main_count], 32
call prepare_playlist
cmp [play_count], 0
je .clear
 
cmp [play_count], 0
je .exit
lea eax, [fpu_state+16]
and eax, -16 ;must be 16b aligned
call FpuSave
mov [main_count], 32;
.l00:
mov [mix_buff_map], 0x0000FFFF;
xor eax, eax
mov [mixCounter], eax
mov [mixIndex],eax
mov [streamIndex], eax;
mov ebx, [play_count]
mov [inputCount], ebx
.l0:
mov ecx, 4
.l1:
mov ebx, [streamIndex]
mov esi, [play_list+ebx*4]
mov eax, [esi+STREAM.work_read]
add [esi+STREAM.work_read], 512
 
mov ebx, [mixIndex]
mov [mix_input+ebx*4], eax
inc [mixCounter]
inc [mixIndex]
inc [streamIndex]
dec [inputCount]
jz .m2
call update_stream
.mix:
lea eax, [mix_list]
call do_mix_list
test eax, eax
je .done
 
dec ecx
jnz .l1
; cmp eax, 1
; je .copy
 
cmp [mixCounter], 4
jnz .m2
 
stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12]
sub [mixIndex],4
mov ebx, [mixIndex]
mov [mix_input+ebx*4], eax
inc [mixIndex]
mov [mixCounter], 0
 
cmp [inputCount], 0
jnz .l0
.m2:
cmp [mixIndex], 1
jne @f
stdcall copy_mem, [output], [mix_input]
jmp .m3
lea ebx, [mix_list]
stdcall mix_all, [output], ebx, eax
@@:
cmp [mixIndex], 2
jne @f
stdcall mix_2_1, [output], [mix_input], [mix_input+4]
jmp .m3
@@:
cmp [mixIndex], 3
jne @f
stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8]
jmp .m3
@@:
stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12]
.m3:
add [output],512
 
dec [main_count]
jnz .l00
 
call update_stream
emms
jnz .mix
.exit:
lea eax, [fpu_state+16]
and eax, -16
call FpuRestore
ret
.exit:
.copy:
lea eax, [mix_list]
stdcall copy_mem, [output], [eax]
jmp @B
.done:
mov ecx, [main_count]
shl ecx, 7 ;ecx*= 512/4
 
mov edi, [output]
mov ecx, 0x1000
xor eax, eax
cld
rep stosd
jmp .exit
.clear:
mov edi, [output]
mov ecx, 4096
xor eax, eax
cld
rep stosd
ret
endp
 
120,157 → 91,252
mov edx, [stream_index]
mov esi, [play_list+edx*4]
 
mov eax, [esi+STREAM.work_read]
cmp eax, [esi+STREAM.work_top]
mov eax, [esi+STREAM.out_rp]
cmp eax, [esi+STREAM.out_top]
jb @f
sub eax, 64*1024
@@:
mov [esi+STREAM.work_read], eax
mov [esi+STREAM.out_rp], eax
 
cmp [esi+STREAM.format], PCM_2_16_48
cmp word [esi+STREAM.format], PCM_2_16_48
je .copy
 
sub [esi+STREAM.work_count], 16384
cmp [esi+STREAM.out_count], 16384
ja .skip
 
cmp [esi+STREAM.work_count], 32768
ja @f
test [esi+STREAM.format], PCM_RING
jnz .ring
 
stdcall refill, esi
@@:
.skip:
inc [stream_index]
dec [play_count]
jnz .l1
ret
 
.ring:
stdcall refill_ring, esi
jmp .skip
.copy:
mov ebx, esi
mov edi, [ebx+STREAM.work_write]
cmp edi, [ebx+STREAM.work_top]
mov edi, [ebx+STREAM.out_wp]
cmp edi, [ebx+STREAM.out_top]
jb @f
 
sub edi, 64*1024
mov [ebx+STREAM.work_write], edi
mov [ebx+STREAM.out_wp], edi
@@:
mov esi, [ebx+STREAM.curr_seg]
mov esi, [ebx+STREAM.in_rp]
mov ecx, 16384/4
cld
rep movsd
 
mov [ebx+STREAM.work_write], edi
mov [ebx+STREAM.out_wp], edi
 
cmp esi, [ebx+STREAM.lim_0]
cmp esi, [ebx+STREAM.in_top]
jb @f
 
mov esi, [ebx+STREAM.seg_0]
mov eax, [ebx+STREAM.lim_0]
xchg esi, [ebx+STREAM.seg_1]
xchg eax, [ebx+STREAM.lim_1]
mov [ebx+STREAM.seg_0], esi
mov [ebx+STREAM.lim_0], eax
sub esi, 0x10000
@@:
mov [ebx+STREAM.curr_seg], esi
mov [ebx+STREAM.in_rp], esi
 
xor ecx, ecx
cmp esi, [ebx+STREAM.notify_off2]
je @f
 
mov ecx,0x8000
cmp esi, [ebx+STREAM.notify_off1]
je @f
 
test eax, eax
jz .l_end
mov eax, [ebx+STREAM.notify_event]
mov ebx, [ebx+STREAM.notify_id]
mov ecx, EVENT_WATCHED
xor edx, edx
call RaiseEvent ;eax, ebx, ecx, edx
.l_end:
inc [stream_index]
dec [play_count]
jnz .l1
ret
endp
 
align 4
proc refill stdcall, str:dword
locals
r_size rd 1
event rd 6
endl
 
mov ebx, [str]
mov edi, [ebx+STREAM.out_wp]
cmp edi, [ebx+STREAM.out_top]
jb @F
sub edi, 0x10000
mov [ebx+STREAM.out_wp], edi
@@:
mov [ev_code], 0xFF000001
mov [ev_offs], ecx
mov eax, [ebx+STREAM.pid]
mov eax, [ebx+STREAM.in_count]
test eax, eax
jz .done
 
lea edx, [ev_code]
push ebx
stdcall SendEvent, eax, edx
pop ebx
mov ecx, [ebx+STREAM.r_size]
cmp eax, ecx
jle @F
 
mov eax, ecx
@@:
mov ecx, eax
cmp word [ebx+STREAM.format], PCM_1_16_8
ja @F
 
shr eax, 1 ;two channles
@@:
test [ebx+STREAM.format], 1 ;even formats mono
jz @F
 
shr eax, 1 ;eax= samples
@@:
shl eax, 15 ;eax*=32768 =r_end
 
mov [r_size], ecx
 
mov esi, [ebx+STREAM.in_rp]
mov edi, [ebx+STREAM.out_wp]
 
stdcall [ebx+STREAM.resample], edi, esi, \
[ebx+STREAM.r_dt], ecx, eax
 
mov ebx, [str]
 
add [ebx+STREAM.out_count], eax;
add [ebx+STREAM.out_wp], eax;
 
mov eax, [ebx+STREAM.in_rp]
mov ecx, [r_size]
add eax, ecx
add [ebx+STREAM.in_free], ecx
sub [ebx+STREAM.in_count], ecx
 
cmp eax, [ebx+STREAM.in_top]
jb @f
 
sub eax, [ebx+STREAM.in_size]
@@:
mov [ebx+STREAM.in_rp], eax
 
.done:
mov eax, [ebx+STREAM.notify_event]
test eax, eax
jnz .l_end
jz .exit
 
not eax
mov [ebx+STREAM.pid], eax ;-1
.l_end:
inc [stream_index]
dec [play_count]
jnz .l1
mov ebx, [ebx+STREAM.notify_id]
mov ecx, EVENT_WATCHED
xor edx, edx
call RaiseEvent ;eax, ebx, ecx, edx
.exit:
ret
endp
 
align 4
proc refill stdcall, str:dword
proc refill_ring stdcall, str:dword
locals
ev_code dd ? ;EVENT
ev_offs dd ?
rd 4
event rd 6
endl
 
mov ebx, [str]
mov edi, [ebx+STREAM.work_write]
cmp edi, [ebx+STREAM.work_top]
mov edi, [ebx+STREAM.out_wp]
cmp edi, [ebx+STREAM.out_top]
jb @F
sub edi, 64*1024
mov [ebx+STREAM.work_write], edi
sub edi, 0x10000
mov [ebx+STREAM.out_wp], edi
@@:
mov esi, [ebx+STREAM.curr_seg]
mov edi, [ebx+STREAM.work_write]
mov ecx, [ebx+STREAM.r_size]
mov eax, ecx
cmp word [ebx+STREAM.format], PCM_1_16_8
ja @F
 
shr eax, 1 ;two channles
@@:
test [ebx+STREAM.format], 1 ;even formats mono
jz @F
 
shr eax, 1 ;eax= samples
@@:
shl eax, 15 ;eax*=32768 =r_end
 
mov esi, [ebx+STREAM.in_rp]
mov edi, [ebx+STREAM.out_wp]
 
stdcall [ebx+STREAM.resample], edi, esi, \
[ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end]
[ebx+STREAM.r_dt], ecx, eax
 
mov ebx, [str]
 
add [ebx+STREAM.work_count], eax;
add [ebx+STREAM.work_write], eax;
add [ebx+STREAM.out_count], eax;
add [ebx+STREAM.out_wp], eax;
 
mov eax, [ebx+STREAM.curr_seg]
add eax, [ebx+STREAM.r_size]
cmp eax, [ebx+STREAM.lim_0]
mov eax, [ebx+STREAM.in_rp]
mov ecx, [ebx+STREAM.r_size]
add eax, ecx
add [ebx+STREAM.in_free], ecx
sub [ebx+STREAM.in_count], ecx
 
cmp eax, [ebx+STREAM.in_top]
jb @f
 
mov esi, [ebx+STREAM.seg_0]
lea edi, [esi-128]
add esi, 0x7F80
mov ecx, 128/4
cld
rep movsd
 
mov eax, [ebx+STREAM.seg_0]
mov ecx, [ebx+STREAM.lim_0]
xchg eax, [ebx+STREAM.seg_1]
xchg ecx, [ebx+STREAM.lim_1]
mov [ebx+STREAM.seg_0], eax
mov [ebx+STREAM.lim_0], ecx
sub eax, [ebx+STREAM.in_size]
@@:
mov [ebx+STREAM.curr_seg], eax
mov [ebx+STREAM.in_rp], eax
 
sub eax, [ebx+STREAM.in_base]
sub eax, 128
lea edx, [event]
 
mov dword [edx], RT_INP_EMPTY
mov dword [edx+4], 0
mov dword [edx+8], ebx
mov dword [edx+12], eax
 
mov eax, [ebx+STREAM.notify_event]
test eax, eax
jz .exit
 
mov ebx, [ebx+STREAM.notify_id]
xor ecx, ecx
cmp eax, [ebx+STREAM.notify_off2]
je @f
call RaiseEvent ;eax, ebx, ecx, edx
.exit:
ret
endp
 
mov ecx,0x8000
cmp eax, [ebx+STREAM.notify_off1]
je @f
ret
align 4
proc mix_all stdcall, dest:dword, list:dword, count:dword
 
mov edi, [dest]
mov ebx, 64
.mix:
mov edx, [list]
mov ecx, [count]
 
mov eax, [edx]
movq mm0, [eax]
movd mm1, [edx+4]
punpckldq mm1,mm1
pmulhw mm0, mm1
psllw mm0, 1
 
.mix_loop:
add dword [edx], 8
add edx, 8
dec ecx
jz @F
 
mov eax, [edx]
movq mm1, [eax]
movd mm2, [edx+4]
punpckldq mm2,mm2
pmulhw mm1, mm2
psllw mm1, 1
paddsw mm0, mm1
jmp .mix_loop
@@:
mov [ev_code], 0xFF000001
mov [ev_offs], ecx
mov eax, [ebx+STREAM.pid]
movq [edi], mm0
add edi, 8
dec ebx
jnz .mix
 
lea edx, [ev_code]
push ebx
stdcall SendEvent, eax, edx
pop ebx
test eax, eax
jnz @F
not eax
mov [ebx+STREAM.pid], eax ;-1
@@:
ret
endp
 
289,7 → 355,7
sub edx, 32*2
mov eax, 16
 
align 16
align 4
.l1:
mov ecx, eax
mov esi, eax
342,7 → 408,7
 
mov esi, 16
 
align 16
align 4
.l1:
mov ecx, esi
mov eax, esi
413,7 → 479,7
mov eax, 16
emms
 
align 16
align 4
.l1:
mov ecx, eax
mov esi, eax
466,7 → 532,7
movq mm7,[mm80]
movq mm6,[mm_mask]
 
align 16
align 4
.l1:
mov ecx, eax
mov esi, eax
840,6 → 906,8
and eax, eax
jz .err
 
mov [output], eax
 
mov edi, eax
mov eax, [str0]
mov ebx, [str1]
939,4 → 1007,100
ret
endp
 
if 0
 
align 4
proc new_mix stdcall, output:dword
locals
mixCounter dd ?
mixIndex dd ?
streamIndex dd ?
inputCount dd ?
main_count dd ?
blockCount dd ?
mix_out dd ?
endl
 
call prepare_playlist
 
cmp [play_count], 0
je .exit
call FpuSave
mov [main_count], 32;
.l00:
mov [mix_buff_map], 0x0000FFFF;
xor eax, eax
mov [mixCounter], eax
mov [mixIndex],eax
mov [streamIndex], eax;
mov ebx, [play_count]
mov [inputCount], ebx
.l0:
mov ecx, 4
.l1:
mov ebx, [streamIndex]
mov esi, [play_list+ebx*4]
mov eax, [esi+STREAM.work_read]
add [esi+STREAM.work_read], 512
 
mov ebx, [mixIndex]
mov [mix_input+ebx*4], eax
inc [mixCounter]
inc [mixIndex]
inc [streamIndex]
dec [inputCount]
jz .m2
 
dec ecx
jnz .l1
 
cmp [mixCounter], 4
jnz .m2
 
stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12]
sub [mixIndex],4
mov ebx, [mixIndex]
mov [mix_input+ebx*4], eax
inc [mixIndex]
mov [mixCounter], 0
 
cmp [inputCount], 0
jnz .l0
.m2:
cmp [mixIndex], 1
jne @f
stdcall copy_mem, [output], [mix_input]
jmp .m3
@@:
cmp [mixIndex], 2
jne @f
stdcall mix_2_1, [output], [mix_input], [mix_input+4]
jmp .m3
@@:
cmp [mixIndex], 3
jne @f
stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8]
jmp .m3
@@:
stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12]
.m3:
add [output],512
 
dec [main_count]
jnz .l00
 
call update_stream
emms
call FpuRestore
ret
.exit:
mov edi, [output]
mov ecx, 0x1000
xor eax, eax
cld
rep stosd
ret
endp
 
end if