/drivers/audio/infinity/infinity.asm |
---|
0,0 → 1,1454 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2006-2014. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Serge 2006-2008 |
; email: infinity_sound@mail.ru |
format PE DLL native 0.05 |
entry START |
DEBUG equ 1 |
CURRENT_API equ 0x0101 ;1.01 |
COMPATIBLE_API equ 0x0100 ;1.00 |
API_VERSION equ (COMPATIBLE_API shl 16) or CURRENT_API |
SOUND_VERSION equ CURRENT_API |
FORCE_MMX equ 0 ;set to 1 to force use mmx or |
FORCE_MMX_128 equ 0 ;integer sse2 extensions |
;and reduce driver size |
;USE_SSE equ 0 |
USE_SSE2_MIXER equ 0 ;floating point mixer. Disabled by default |
OS_BASE equ 0x80000000 |
CAPS_SSE2 equ 26 |
PG_SW equ 0x003 |
RT_INP_EMPTY equ 0xFF000001 |
RT_OUT_EMPTY equ 0xFF000002 |
RT_INP_FULL equ 0xFF000003 |
RT_OUT_FULL equ 0xFF000004 |
EVENT_WATCHED equ 0x10000000 |
EVENT_SIGNALED equ 0x20000000 |
MANUAL_RESET equ 0x40000000 |
MANUAL_DESTROY equ 0x80000000 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_GET_POS equ 9 |
section '.flat' code readable executable |
include '../../struct.inc' |
include '../../macros.inc' |
include '../../proc32.inc' |
include 'main.inc' |
include '../../peimport.inc' |
proc START c uses ebx esi edi, state:dword, cmdline:dword |
cmp [state], 1 |
jne .exit |
invoke GetService, szSound |
test eax, eax |
jz .fail |
mov [hSound], eax |
invoke KernelAlloc, 16*512 |
test eax, eax |
jz .out_of_mem |
mov [mix_buff], eax |
mov eax, str.fd-FD_OFFSET |
mov [str.fd], eax |
mov [str.bk], eax |
if FORCE_MMX |
if FORCE_MMX_128 |
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 |
stop |
end if |
mov [mix_2_core], mmx_mix_2 |
mov [mix_3_core], mmx_mix_3 |
mov [mix_4_core], mmx_mix_4 |
end if |
if FORCE_MMX_128 |
if FORCE_MMX |
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 |
stop |
end if |
mov [mix_2_core], mmx128_mix_2 |
mov [mix_3_core], mmx128_mix_3 |
mov [mix_4_core], mmx128_mix_4 |
end if |
if 0 |
if ~(FORCE_MMX or FORCE_MMX_128) ;autodetect |
mov eax, 1 |
cpuid |
bt edx, CAPS_SSE2 |
jc .mmx128 |
;old 64-bit mmx |
mov [mix_2_core], mmx_mix_2 |
mov [mix_3_core], mmx_mix_3 |
mov [mix_4_core], mmx_mix_4 |
jmp @F |
.mmx128: ;128-bit integer sse2 extensions |
mov [mix_2_core], mmx128_mix_2 |
mov [mix_3_core], mmx128_mix_3 |
mov [mix_4_core], mmx128_mix_4 |
@@: |
end if |
end if |
stdcall set_handler, [hSound], new_mix |
mov [eng_state], SND_STOP |
invoke RegService, szInfinity, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
invoke SysMsgBoardStr |
end if |
.exit: |
xor eax, eax |
ret |
.out_of_mem: |
if DEBUG |
mov esi, msgMem |
invoke SysMsgBoardStr |
end if |
xor eax, eax |
ret |
endp |
align 4 |
srv_calls dd service_proc.srv_getversion ; 0 |
dd service_proc.snd_create_buff ; 1 |
dd service_proc.snd_destroy_buff ; 2 |
dd service_proc.snd_setformat ; 3 |
dd service_proc.snd_getformat ; 4 |
dd service_proc.snd_reset ; 5 |
dd service_proc.snd_setpos ; 6 |
dd service_proc.snd_getpos ; 7 |
dd service_proc.snd_setbuff ; 8 |
dd service_proc.snd_out ; 9 |
dd service_proc.snd_play ; 10 |
dd service_proc.snd_stop ; 11 |
dd service_proc.snd_setvolume ; 12 |
dd service_proc.snd_getvolume ; 13 |
dd service_proc.snd_setpan ; 14 |
dd service_proc.snd_getpan ; 15 |
dd service_proc.snd_getbuffsize ; 16 |
dd service_proc.snd_getfreespace ; 17 |
dd service_proc.snd_settimebase ; 18 |
dd service_proc.snd_gettimestamp ; 19 |
srv_calls_end: |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+IOCTL.io_code] |
cmp eax, (srv_calls_end-srv_calls)/4 |
ja .fail |
cmp eax, SND_DESTROY_BUFF |
jb @F |
; cmp [edi+inp_size], 4 |
; jb .fali |
mov ebx, [edi+IOCTL.input] |
mov edx, [ebx] |
cmp [edx+STREAM.magic], 'WAVE' |
jne .fail |
cmp [edx+STREAM.size], STREAM.sizeof |
jne .fail |
@@: |
jmp [srv_calls+eax*4] |
.fail: |
mov eax, -1 |
ret |
align 4 |
.srv_getversion: |
mov eax, [edi+IOCTL.output] |
cmp [edi+IOCTL.out_size], 4 |
jne .fail |
mov eax, [eax] |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
align 4 |
.snd_create_buff: |
mov ebx, [edi+IOCTL.input] |
stdcall CreateBuffer, [ebx], [ebx+4] |
mov edi, [ioctl] |
mov ecx, [edi+IOCTL.output] |
mov ecx, [ecx] |
mov [ecx], ebx |
ret |
align 4 |
.snd_destroy_buff: |
mov eax, edx |
call DestroyBuffer |
ret |
align 4 |
.snd_setformat: |
stdcall SetFormat, edx, [ebx+4] |
ret |
align 4 |
.snd_getformat: |
movzx eax, word [edx+STREAM.format] |
mov ecx, [edi+IOCTL.output] |
mov ecx, [ecx] |
mov [ecx], eax |
xor eax, eax |
ret |
align 4 |
.snd_reset: |
stdcall ResetBuffer, edx, [ebx+4] |
ret |
align 4 |
.snd_setpos: |
stdcall SetBufferPos, edx, [ebx+4] |
ret |
align 4 |
.snd_getpos: |
stdcall GetBufferPos, edx |
mov edi, [ioctl] |
mov ecx, [edi+IOCTL.output] |
mov ecx, [ecx] |
mov [ecx], ebx |
ret |
align 4 |
.snd_setbuff: |
mov eax, [ebx+4] |
stdcall set_buffer, edx, eax, [ebx+8], [ebx+12] |
ret |
align 4 |
.snd_out: |
mov eax, [ebx+4] |
stdcall wave_out, edx, eax, [ebx+8] |
ret |
align 4 |
.snd_play: |
stdcall play_buffer, edx, [ebx+4] |
ret |
align 4 |
.snd_stop: |
stdcall stop_buffer, edx |
ret |
align 4 |
.snd_setvolume: |
stdcall SetBufferVol, edx, [ebx+4], [ebx+8] |
ret |
align 4 |
.snd_getvolume: |
mov eax, [edi+IOCTL.output] |
mov ecx, [eax] |
mov eax, [eax+4] |
stdcall GetBufferVol, edx, ecx, eax |
ret |
align 4 |
.snd_setpan: |
stdcall SetBufferPan, edx, [ebx+4] |
ret |
align 4 |
.snd_getpan: |
mov eax, [edx+STREAM.pan] |
mov ebx, [edi+IOCTL.output] |
mov ebx, [ebx] |
mov [ebx], eax |
xor eax, eax |
ret |
align 4 |
.snd_getbuffsize: |
mov eax, [edx+STREAM.in_size] |
mov ecx, [edi+IOCTL.output] |
mov ecx, [ecx] |
mov [ecx], eax |
xor eax, eax |
ret |
align 4 |
.snd_getfreespace: |
test [edx+STREAM.format], PCM_OUT |
jz .fail |
mov ebx, [edx+STREAM.in_free] |
mov ecx, [edi+IOCTL.output] |
mov [ecx], ebx |
xor eax, eax |
ret |
align 4 |
.snd_settimebase: |
cmp [edi+IOCTL.inp_size], 12 |
jne .fail |
mov eax, [ebx+4] |
mov ebx, [ebx+8] |
pushfd |
cli |
mov dword [edx+STREAM.time_base], eax |
mov dword [edx+STREAM.time_base+4], ebx |
xor eax, eax |
mov dword [edx+STREAM.time_stamp], eax |
mov dword [edx+STREAM.time_stamp+4], eax |
popfd |
ret |
align 4 |
.snd_gettimestamp: |
cmp [edi+IOCTL.out_size], 8 |
jne .fail |
pushfd |
cli |
xor ebx, ebx |
push 48 |
push ebx ; local storage |
cmp [edx+STREAM.flags], SND_STOP |
je @F |
mov eax, esp |
push ebx |
push ecx |
push edx |
push esi |
push edi |
push 4 ;.out_size |
push eax ;.output |
push ebx ;.inp_size |
push ebx ;.input |
push DEV_GET_POS ;.code |
push dword [hSound] ;.handle |
mov eax, esp |
invoke ServiceHandler, eax |
add esp, 6*4 |
pop edi |
pop esi |
pop edx |
pop ecx |
pop ebx |
test eax, eax |
jz @F |
mov dword [esp], 0 ; clear offset |
@@: |
mov edi, [edi+IOCTL.output] |
emms |
fild qword [edx+STREAM.time_stamp] |
fiadd dword [esp] ; primary buffer offset |
fidiv dword [esp+4] ; total_samples / frequency |
fadd qword [edx+STREAM.time_base] |
fstp qword [edi] |
add esp, 8 |
popfd |
xor eax, eax |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc CreateBuffer stdcall, format:dword, size:dword |
locals |
str dd ? |
ring_size dd ? |
ring_pages dd ? |
endl |
mov eax, [format] |
cmp ax, PCM_1_8_8 |
ja .fail |
test eax, PCM_OUT |
jnz .test_out |
test eax, PCM_RING |
jnz .test_ring |
;staic |
test eax, PCM_STATIC |
jz .test_out ;use PCM_OUT as default format |
jmp .test_ok |
.test_out: |
test eax, PCM_RING+PCM_STATIC |
jnz .fail |
or [format], PCM_OUT ;force set |
jmp .test_ok |
.test_ring: |
test eax, PCM_OUT+PCM_STATIC |
jnz .fail |
.test_ok: |
invoke GetPid |
mov ebx, eax |
mov eax, STREAM.sizeof |
invoke CreateObject |
test eax, eax |
jz .fail |
mov [str], eax |
mov ebx, [format] |
mov [eax+STREAM.format], ebx |
xor ecx, ecx |
movzx ebx, bx |
cmp ebx, 19 |
jb @f |
mov ecx, 0x80808080 |
@@: |
mov [eax+STREAM.r_silence], ecx |
shl ebx, 2 |
lea ebx, [ebx+ebx*2] ;ebx*=12 |
mov ecx, [resampler_params+ebx] |
mov edx, [resampler_params+ebx+4] |
mov esi, [resampler_params+ebx+8] |
mov [eax+STREAM.r_size], ecx |
mov [eax+STREAM.r_dt], edx |
mov [eax+STREAM.resample], esi |
xor ecx, ecx |
mov [eax+STREAM.l_vol], ecx |
mov [eax+STREAM.r_vol], ecx |
mov dword [eax+STREAM.l_amp], 0x7FFF7FFF |
mov [eax+STREAM.pan], ecx |
test [format], PCM_STATIC |
jnz .static |
; ring and waveout |
mov ebx, 0x10000 |
test [format], PCM_RING |
jz .waveout |
mov ebx, [eax+STREAM.r_size] |
add ebx, 4095 |
and ebx, -4096 |
add ebx, ebx |
.waveout: |
mov [ring_size], ebx |
mov eax, ebx |
shr ebx, 12 |
mov [ring_pages], ebx |
invoke CreateRingBuffer, eax, PG_SW |
mov edi, [str] |
mov ecx, [ring_size] |
mov [edi+STREAM.in_base], eax |
mov [edi+STREAM.in_size], ecx |
add eax, 128 |
mov [edi+STREAM.in_wp], eax |
mov [edi+STREAM.in_rp], eax |
mov [edi+STREAM.in_count], 0 |
mov [edi+STREAM.in_free], ecx |
add eax, ecx |
mov [edi+STREAM.in_top], eax |
jmp .out_buff |
.static: |
mov ecx, [size] |
add ecx, 128 ;resampler required |
mov [eax+STREAM.in_size], ecx |
invoke KernelAlloc, ecx |
mov edi, [str] |
mov [edi+STREAM.in_base], eax |
add eax, 128 |
mov [edi+STREAM.in_wp], eax |
mov [edi+STREAM.in_rp], eax |
mov ebx, [size] |
mov [edi+STREAM.in_count], ebx |
mov [edi+STREAM.in_free], ebx |
add eax, ebx |
mov [edi+STREAM.in_top], eax |
.out_buff: |
invoke AllocKernelSpace, dword 128*1024 |
mov edi, [str] |
xor ebx, ebx |
mov [edi+STREAM.out_base], eax |
mov [edi+STREAM.out_wp], eax |
mov [edi+STREAM.out_rp], eax |
mov [edi+STREAM.out_count], ebx |
add eax, 64*1024 |
mov [edi+STREAM.out_top], eax |
mov dword [edi+STREAM.time_base], ebx |
mov dword [edi+STREAM.time_base+4], ebx |
mov dword [edi+STREAM.time_stamp], ebx |
mov dword [edi+STREAM.time_stamp+4], ebx |
mov dword [edi+STREAM.last_ts], ebx |
invoke AllocPages, dword 64/4 |
mov edi, [str] |
mov ebx, [edi+STREAM.out_base] |
mov ecx, 16 |
or eax, PG_SW |
push eax |
push ebx |
invoke CommitPages ;eax, ebx, ecx |
mov ecx, 16 |
pop ebx |
pop eax |
add ebx, 64*1024 |
invoke CommitPages ;double mapped |
mov edi, [str] |
mov ecx, [edi+STREAM.in_top] |
mov edi, [edi+STREAM.in_base] |
sub ecx, edi |
xor eax, eax |
shr ecx, 2 |
cld |
rep stosd |
mov edi, [str] |
mov edi, [edi+STREAM.out_base] |
mov ecx, (64*1024)/4 |
rep stosd |
xor esi, esi |
mov ecx, MANUAL_DESTROY |
invoke CreateEvent |
mov ebx, [str] |
mov [ebx+STREAM.notify_event], eax |
mov [ebx+STREAM.notify_id], edx |
mov [ebx+STREAM.magic], 'WAVE' |
mov [ebx+STREAM.destroy], DestroyBuffer.destroy |
mov [ebx+STREAM.size], STREAM.sizeof |
mov [ebx+STREAM.flags], SND_STOP |
pushf |
cli |
mov eax, str.fd-FD_OFFSET |
mov edx, [eax+STREAM.str_fd] |
mov [ebx+STREAM.str_fd], edx |
mov [ebx+STREAM.str_bk], eax |
mov [eax+STREAM.str_fd], ebx |
mov [edx+STREAM.str_bk], ebx |
popf |
xor eax, eax |
ret |
.fail: |
xor ebx, ebx |
or eax, -1 |
ret |
endp |
;param |
; eax= buffer handle |
align 4 |
DestroyBuffer: |
.handle equ esp ;local |
mov [eax+STREAM.flags], SND_STOP |
.destroy: |
push eax |
pushfd |
cli |
mov ebx, [eax+STREAM.str_fd] |
mov ecx, [eax+STREAM.str_bk] |
mov [ebx+STREAM.str_bk], ecx |
mov [ecx+STREAM.str_fd], ebx |
popf |
invoke KernelFree, [eax+STREAM.in_base] |
mov eax, [.handle] |
invoke KernelFree, [eax+STREAM.out_base] |
pop eax ;restore stack |
invoke DestroyObject ;eax= stream |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
restore .handle |
align 4 |
proc SetFormat stdcall, str:dword, format:dword |
cmp word [format], PCM_1_8_8 |
ja .fail |
mov edx, [str] |
mov [edx+STREAM.flags], SND_STOP |
test [edx+STREAM.format], PCM_RING |
jnz .fail |
; mov eax,[edx+STREAM.out_base] |
; mov [edx+STREAM.out_wp], eax |
; mov [edx+STREAM.out_rp], eax |
; mov [edx+STREAM.out_count], 0 |
movzx eax, word [format] |
mov word [edx+STREAM.format], ax |
xor ebx, ebx |
cmp eax, 19 |
jb @f |
mov ebx, 0x80808080 |
@@: |
mov [edx+STREAM.r_silence], ebx |
shl eax, 2 |
lea eax, [eax+eax*2] ;eax*=12 |
mov edi, [resampler_params+eax] |
mov ecx, [resampler_params+eax+4] |
mov ebx, [resampler_params+eax+8] |
mov [edx+STREAM.r_size], edi |
mov [edx+STREAM.r_dt], ecx |
mov [edx+STREAM.resample], ebx |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static buffers only |
; use waveout for streams |
align 4 |
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_OUT |
jnz .fail |
mov esi, [src] |
mov edi, [offs] |
add edi, [edx+STREAM.in_base] |
add edi, 128 |
cmp edi, [edx+STREAM.in_top] |
jae .fail |
mov ecx, [size] |
lea ebx, [ecx+edi] |
sub ebx, [edx+STREAM.in_top] |
jb @F |
sub ecx, ebx |
@@: |
shr ecx, 2 |
cld |
rep movsd |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for stream buffers only |
align 4 |
proc wave_out stdcall, str:dword,src:dword,size:dword |
locals |
state_saved dd ? |
fpu_state rb 528 |
endl |
mov edx, [str] |
mov eax, [edx+STREAM.format] |
test eax, PCM_OUT |
jz .fail |
cmp ax, PCM_ALL |
je .fail |
mov esi, [src] |
test esi, esi |
jz .fail |
cmp esi, OS_BASE |
jae .fail |
mov [state_saved], 0 |
.main_loop: |
mov edx, [str] |
mov ebx, [size] |
test ebx, ebx |
jz .done |
cmp [edx+STREAM.flags], SND_STOP |
jne .fill |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
mov ecx, [edx+STREAM.in_size] |
sub ecx, 128 |
mov [edx+STREAM.in_wp], edi |
mov [edx+STREAM.in_rp], edi |
mov [edx+STREAM.in_count], 0 |
mov [edx+STREAM.in_free], ecx |
mov eax, [edx+STREAM.out_base] |
mov [edx+STREAM.out_wp], eax |
mov [edx+STREAM.out_rp], eax |
mov [edx+STREAM.out_count], 0 |
.fill: |
cli |
mov ecx, [edx+STREAM.in_free] |
test ecx, ecx |
jz .wait |
cmp ecx, ebx |
jbe @F |
mov ecx, ebx |
@@: |
sub [size], ecx |
add [edx+STREAM.in_count], ecx |
sub [edx+STREAM.in_free], ecx |
shr ecx, 2 |
mov edi, [edx+STREAM.in_wp] |
mov esi, [src] |
cld |
rep movsd |
mov [src], esi |
cmp edi, [edx+STREAM.in_top] |
jb @F |
sub edi, [edx+STREAM.in_size] |
@@: |
mov [edx+STREAM.in_wp], edi |
cmp [edx+STREAM.out_count], 32768 |
jae .skip |
cmp [state_saved], 0 |
jne @F |
lea eax, [fpu_state+15] |
and eax, -16 |
invoke FpuSave |
mov [state_saved], 1 |
@@: |
stdcall refill, edx |
.skip: |
sti |
mov edx, [str] |
mov [edx+STREAM.flags], SND_PLAY |
cmp [eng_state], SND_PLAY |
je .main_loop |
stdcall dev_play, [hSound] |
mov [eng_state], SND_PLAY |
jmp .main_loop |
.wait: |
sti |
mov edx, [str] |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
invoke WaitEvent ;eax ebx |
jmp .main_loop |
.done: |
cmp [state_saved], 1 |
jne @F |
lea eax, [fpu_state+15] |
and eax, -16 |
invoke FpuRestore |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; both static and stream |
; reset all but not clear buffers |
; flags reserved |
; RESET_INPUT equ 1 ;reset and clear input buffer |
; RESET_OUTPUT equ 2 ;reset and clear output buffer |
; RESET_ALL equ 3 |
align 4 |
proc ResetBuffer stdcall, str:dword, flags:dword |
mov edx, [str] |
mov [edx+STREAM.flags], SND_STOP |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
mov [edx+STREAM.in_wp], edi |
mov [edx+STREAM.in_rp], edi |
test [edx+STREAM.flags], PCM_STATIC |
jnz .static |
mov [edx+STREAM.in_count], 0 |
jmp @F |
.static: |
mov eax, [edx+STREAM.in_size] |
mov [edx+STREAM.in_count], eax |
@@: |
mov eax, [edx+STREAM.in_size] |
sub eax, 128 |
mov [edx+STREAM.in_free], eax |
xor eax, eax |
mov ebx, [edx+STREAM.out_base] |
mov [edx+STREAM.out_wp], ebx |
mov [edx+STREAM.out_rp], ebx |
mov [edx+STREAM.out_count], eax |
mov dword [edx+STREAM.time_base], eax |
mov dword [edx+STREAM.time_base+4], eax |
mov dword [edx+STREAM.time_stamp], eax |
mov dword [edx+STREAM.time_stamp+4], eax |
mov dword [edx+STREAM.last_ts], eax |
mov eax, [edx+STREAM.r_silence] |
test [flags], 1 |
jz @F |
mov ecx, [edx+STREAM.in_top] |
mov edi, [edx+STREAM.in_base] |
sub ecx, edi |
shr ecx, 2 |
cld |
rep stosd |
@@: |
test [flags], 2 |
jz @F |
mov edi, [edx+STREAM.out_base] |
mov ecx, (64*1024)/4 |
rep stosd |
@@: |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static buffers only |
align 4 |
proc SetBufferPos stdcall, str:dword, pos:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_STATIC |
jz .fail |
mov [edx+STREAM.flags], SND_STOP |
mov eax, [pos] |
add eax, [edx+STREAM.in_base] |
mov ebx, [edx+STREAM.in_top] |
add eax, 128 |
cmp eax, ebx |
jae .fail |
mov [edx+STREAM.in_rp], eax |
sub ebx, eax |
mov [edx+STREAM.in_count], ebx |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
align 4 |
proc GetBufferPos stdcall, str:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_STATIC |
jz .fail |
mov ebx, [edx+STREAM.in_rp] |
sub ebx, [edx+STREAM.in_base] |
sub ebx, 128 |
xor eax, eax |
ret |
.fail: |
xor ebx, ebx |
or eax, -1 |
ret |
endp |
; both |
align 4 |
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword |
mov edx, [str] |
stdcall set_vol_param, [l_vol], [r_vol], [edx+STREAM.pan] |
ret |
endp |
proc minw stdcall, arg1:dword, arg2:dword |
mov ax, word [arg1] |
cmp ax, word [arg2] |
jle @f |
mov eax, [arg2] |
@@: |
ret |
endp |
proc maxw stdcall, arg1:dword, arg2:dword |
mov ax, word [arg1] |
cmp ax, word [arg2] |
jge @f |
mov eax, [arg2] |
@@: |
ret |
endp |
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword |
locals |
_600 dd ? |
_32767 dd ? |
state rb 108 |
endl |
mov [_600], 0x44160000 ;600.0 |
mov [_32767], 32767 |
lea ebx, [state] |
fnsave [ebx] |
stdcall minw, [l_vol], [vol_max] |
stdcall maxw, eax, [vol_min] |
mov [l_vol], eax |
mov [edx+STREAM.l_vol], eax |
stdcall minw, [r_vol], [vol_max+4] |
stdcall maxw, eax, [vol_min+4] |
mov [r_vol], eax |
mov [edx+STREAM.r_vol], eax |
stdcall minw, [pan], [pan_max] |
stdcall maxw, eax, [vol_min] |
mov [edx+STREAM.pan], eax |
cmp word [edx+STREAM.pan], 0 |
jl @f |
mov ebx, [l_vol] |
sub ebx, eax |
stdcall minw, ebx, [vol_max] |
stdcall maxw, eax, [vol_min] |
mov [l_vol], eax |
jmp .calc_amp |
@@: |
mov ebx, [r_vol] |
add ebx, [pan] |
stdcall minw, ebx, [vol_max+4] |
stdcall maxw, eax, [vol_min+4] |
mov [r_vol], eax |
.calc_amp: |
emms |
fild word [l_vol] |
call .calc |
fistp word [edx+STREAM.l_amp] |
fstp dword [edx+STREAM.l_amp_f] |
fstp st0 |
fild word [r_vol] |
call .calc |
fistp word [edx+STREAM.r_amp] |
fstp dword [edx+STREAM.r_amp_f] |
fstp st0 |
fnclex |
lea ebx, [state] |
frstor [ebx] |
xor eax, eax |
inc eax |
ret |
.calc: |
fdiv dword [_600] |
fld st0 |
frndint |
fxch st1 |
fsub st, st1 |
f2xm1 |
fld1 |
faddp st1, st0 |
fscale |
fld st0 |
fimul dword [_32767] |
ret 0 |
endp |
align 4 |
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword |
mov edx, [str] |
mov eax, [p_lvol] |
movsx ecx, word [edx+STREAM.l_vol] |
mov [eax], ecx |
mov eax, [p_rvol] |
movsx ecx, word [edx+STREAM.r_vol] |
mov [eax], ecx |
xor eax, eax |
ret |
endp |
align 4 |
proc SetBufferPan stdcall, str:dword,pan:dword |
mov edx, [str] |
stdcall set_vol_param, [edx+STREAM.l_vol], \ |
[edx+STREAM.r_vol],[pan] |
ret |
endp |
; for static and ring buffers only |
align 4 |
proc play_buffer stdcall, str:dword, flags:dword |
mov ebx, [str] |
mov eax, [ebx+STREAM.format] |
test eax, PCM_OUT |
jnz .fail |
cmp ax, PCM_ALL |
je .fail |
mov [ebx+STREAM.flags], SND_PLAY |
cmp [eng_state], SND_PLAY |
je .done |
stdcall dev_play, [hSound] |
mov [eng_state], SND_PLAY |
.done: |
test [flags], PLAY_SYNC |
jz @F |
mov edx, [str] |
.wait: |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
invoke WaitEvent ;eax ebx |
mov edx, [str] |
cmp [edx+STREAM.flags], SND_STOP |
jne .wait |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static and ring buffers only |
align 4 |
proc stop_buffer stdcall, str:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_STATIC+PCM_RING |
jz .fail |
mov [edx+STREAM.flags], SND_STOP |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
invoke ClearEvent ;eax ebx |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; param |
; eax= mix_list |
align 4 |
do_mix_list: |
xor edx, edx |
mov esi, str.fd-FD_OFFSET |
mov ebx, [esi+STREAM.str_fd] |
@@: |
cmp ebx, esi |
je .done |
cmp [ebx+STREAM.magic], 'WAVE' |
jne .next |
cmp [ebx+STREAM.size], STREAM.sizeof |
jne .next |
cmp [ebx+STREAM.flags], SND_PLAY; |
jne .next |
mov ecx, [ebx+STREAM.out_count] |
test ecx, ecx |
jnz .l1 |
test [ebx+STREAM.format], PCM_RING |
jnz .next |
mov [ebx+STREAM.flags], SND_STOP |
jmp .next |
.l1: |
cmp ecx, 512 |
jae .add_buff |
mov edi, [ebx+STREAM.out_rp] |
add edi, ecx |
sub ecx, 512 |
neg ecx |
push eax |
xor eax, eax |
cld |
rep stosb |
pop eax |
mov [ebx+STREAM.out_count], 512 |
.add_buff: |
mov ecx, [ebx+STREAM.out_rp] |
mov [eax], ecx |
if USE_SSE2_MIXER |
mov edi, dword [ebx+STREAM.l_amp_f] |
mov [eax+4], edi |
mov edi, dword [ebx+STREAM.r_amp_f] |
mov [eax+8], edi |
else |
mov edi, dword [ebx+STREAM.l_amp] |
mov [eax+4], edi |
end if |
add [ebx+STREAM.out_rp], 512 |
sub [ebx+STREAM.out_count], 512 |
add eax, 12 |
inc edx |
.next: |
mov ebx, [ebx+STREAM.str_fd] |
jmp @B |
.done: |
mov eax, edx |
ret |
align 4 |
prepare_playlist: |
xor edx, edx |
mov [play_count], edx |
mov esi, str.fd-FD_OFFSET |
mov edi, [esi+STREAM.str_fd] |
@@: |
cmp edi, esi |
je .done |
cmp [edi+STREAM.magic], 'WAVE' |
jne .next |
cmp [edi+STREAM.size], STREAM.sizeof |
jne .next |
cmp [edi+STREAM.flags], SND_PLAY; |
jne .next |
mov [play_list+edx], edi |
inc [play_count] |
add edx, 4 |
.next: |
mov edi, [edi+STREAM.str_fd] |
jmp @B |
.done: |
ret |
align 4 |
proc set_handler stdcall, hsrv:dword, handler_proc:dword |
locals |
handler dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
val dd ? |
endl |
mov eax, [hsrv] |
lea ecx, [handler_proc] |
xor ebx, ebx |
mov [handler], eax |
mov [io_code], DEV_CALLBACK |
mov [input], ecx |
mov [inp_size], 4 |
mov [output], ebx |
mov [out_size], 0 |
lea eax, [handler] |
invoke ServiceHandler, eax |
ret |
endp |
align 4 |
proc dev_play stdcall, hsrv:dword |
locals |
handle dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
val dd ? |
endl |
mov eax, [hsrv] |
xor ebx, ebx |
mov [handle], eax |
mov [io_code], DEV_PLAY |
mov [input], ebx |
mov [inp_size], ebx |
mov [output], ebx |
mov [out_size], ebx |
lea eax, [handle] |
invoke ServiceHandler, eax |
ret |
endp |
if 0 |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
end if |
include 'mixer.asm' |
include 'mix_mmx.inc' |
include 'mix_sse2.inc' |
;if USE_SSE |
; include 'mix_sse.inc' |
;end if |
align 16 |
resampler_params: |
;r_size r_dt resampler_func |
dd 0,0,0 ; 0 PCM_ALL |
dd 16384, 0, copy_stream ; 1 PCM_2_16_48 |
dd 8192, 0, m16_stereo ; 2 PCM_1_16_48 |
dd 16384, 30109, resample_2 ; 3 PCM_2_16_44 |
dd 8192, 30109, resample_1 ; 4 PCM_1_16_44 |
dd 16384, 21846, resample_2 ; 5 PCM_2_16_32 |
dd 8192, 21846, resample_1 ; 6 PCM_1_16_32 |
dd 16384, 16384, resample_2 ; 7 PCM_2_16_24 |
dd 8192, 16384, resample_1 ; 8 PCM_1_16_24 |
dd 8192, 15052, resample_2 ; 9 PCM_2_16_22 |
dd 4096, 15052, resample_1 ;10 PCM_1_16_22 |
dd 8192, 10923, resample_2 ;11 PCM_2_16_16 |
dd 4096, 10923, resample_1 ;12 PCM_1_16_16 |
dd 8192, 8192, resample_2 ;13 PCM_2_16_12 |
dd 4096, 8192, resample_1 ;14 PCM_1_16_12 |
dd 4096, 7527, resample_2 ;15 PCM_2_16_11 |
dd 2048, 7527, resample_1 ;16 PCM_1_16_11 |
dd 4096, 5462, resample_2 ;17 PCM_2_16_8 |
dd 2048, 5462, resample_1 ;18 PCM_1_16_8 |
dd 16384, 0, s8_stereo ;19 PCM_2_8_48 |
dd 8192, 0, m8_stereo ;20 PCM_1_8_48 |
dd 8192, 30109, resample_28 ;21 PCM_2_8_44 |
dd 4096, 30109, resample_18 ;22 PCM_1_8_44 |
dd 8192, 21846, resample_28 ;23 PCM_2_8_32 |
dd 4096, 21846, resample_18 ;24 PCM_1_8_32 |
dd 8192, 16384, resample_28 ;25 PCM_2_8_24 |
dd 4096, 16384, resample_18 ;26 PCM_1_8_24 |
dd 4096, 15052, resample_28 ;27 PCM_2_8_22 |
dd 2048, 15052, resample_18 ;28 PCM_1_8_22 |
dd 4096, 10923, resample_28 ;29 PCM_2_8_16 |
dd 2048, 10923, resample_18 ;30 PCM_1_8_16 |
dd 4096, 8192, resample_28 ;31 PCM_2_8_12 |
dd 2048, 8192, resample_18 ;32 PCM_1_8_12 |
dd 2048, 7527, resample_28 ;33 PCM_2_8_11 |
dd 1024, 7527, resample_18 ;34 PCM_1_8_11 |
dd 2048, 5462, resample_28 ;35 PCM_2_8_8 |
dd 1024, 5462, resample_18 ;36 PCM_1_8_8 |
m7 dw 0x8000,0x8000,0x8000,0x8000 |
mm80 dq 0x8080808080808080 |
mm_mask dq 0xFF00FF00FF00FF00 |
vol_max dd 0x00000000,0x00000000 |
vol_min dd 0x0000D8F0,0x0000D8F0 |
pan_max dd 0x00002710,0x00002710 |
;stream_map dd 0xFFFF ; 16 |
szInfinity db 'INFINITY',0 |
szSound db 'SOUND',0 |
if DEBUG |
msgFail db 'Sound service not loaded',13,10,0 |
msgPlay db 'Play buffer',13,10,0 |
msgStop db 'Stop',13,10,0 |
msgUser db 'User callback',13,10,0 |
msgMem db 'Not enough memory',13,10,0 |
msgDestroy db 'Destroy sound buffer', 13,10,0 |
msgWaveout db 'Play waveout', 13,10,0 |
msgSetVolume db 'Set volume',13,10,0 |
end if |
align 4 |
data fixups |
end data |
section '.data' data readable writable |
play_list rd 16 |
mix_input rd 16 |
play_count rd 1 |
hSound rd 1 |
eng_state rd 1 |
mix_buff rd 1 |
mix_buff_map rd 1 |
str.fd rd 1 |
str.bk rd 1 |
mix_2_core rd 1 |
mix_3_core rd 1 |
mix_4_core rd 1 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/drivers/audio/infinity/main.inc |
---|
0,0 → 1,173 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2006-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Serge 2006-2008 |
; email: infinity_sound@mail.ru |
PLAY_SYNC equ 0x80000000 |
PCM_ALL equ 0 |
PCM_OUT equ 0x08000000 |
PCM_RING equ 0x10000000 |
PCM_STATIC equ 0x20000000 |
PCM_FLOAT equ 0x40000000 ;reserved |
PCM_FILTER equ 0x80000000 ;reserved |
PCM_2_16_48 equ 1 |
PCM_1_16_48 equ 2 |
PCM_2_16_44 equ 3 |
PCM_1_16_44 equ 4 |
PCM_2_16_32 equ 5 |
PCM_1_16_32 equ 6 |
PCM_2_16_24 equ 7 |
PCM_1_16_24 equ 8 |
PCM_2_16_22 equ 9 |
PCM_1_16_22 equ 10 |
PCM_2_16_16 equ 11 |
PCM_1_16_16 equ 12 |
PCM_2_16_12 equ 13 |
PCM_1_16_12 equ 14 |
PCM_2_16_11 equ 15 |
PCM_1_16_11 equ 16 |
PCM_2_16_8 equ 17 |
PCM_1_16_8 equ 18 |
PCM_2_8_48 equ 19 |
PCM_1_8_48 equ 20 |
PCM_2_8_44 equ 21 |
PCM_1_8_44 equ 22 |
PCM_2_8_32 equ 23 |
PCM_1_8_32 equ 24 |
PCM_2_8_24 equ 25 |
PCM_1_8_24 equ 26 |
PCM_2_8_22 equ 27 |
PCM_1_8_22 equ 28 |
PCM_2_8_16 equ 29 |
PCM_1_8_16 equ 30 |
PCM_2_8_12 equ 31 |
PCM_1_8_12 equ 32 |
PCM_2_8_11 equ 33 |
PCM_1_8_11 equ 34 |
PCM_2_8_8 equ 35 |
PCM_1_8_8 equ 36 |
SRV_GETVERSION equ 0 |
SND_CREATE_BUFF equ 1 |
SND_DESTROY_BUFF equ 2 |
SND_SETFORMAT equ 3 |
SND_GETFORMAT equ 4 |
SND_RESET equ 5 |
SND_SETPOS equ 6 |
SND_GETPOS equ 7 |
SND_SETBUFF equ 8 |
SND_OUT equ 9 |
SND_PLAY equ 10 |
SND_STOP equ 11 |
SND_SETVOLUME equ 12 |
SND_GETVOLUME equ 13 |
SND_SETPAN equ 14 |
SND_GETPAN equ 15 |
SND_GETBUFFSIZE equ 16 |
SND_GETFREESPACE equ 17 |
SND_SETTIMEBASE equ 18 |
SND_GETTIMESTAMP equ 19 |
struc STREAM |
{ |
.magic dd ? ;'WAVE' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.size dd ? |
.str_fd dd ? |
.str_bk dd ? |
.device dd ? |
.format dd ? |
.flags dd ? |
.out_base dd ? |
.out_wp dd ? |
.out_rp dd ? |
.out_count dd ? |
.out_top dd ? ;16*4 |
.in_base dd ? |
.in_size dd ? |
.in_wp dd ? |
.in_rp dd ? |
.in_count dd ? |
.in_free dd ? |
.in_top dd ? |
align 8 |
.time_base dq ? |
.time_stamp dq ? |
.last_ts dd ? |
.notify_event dd ? |
.notify_id dd ? |
.r_size dd ? |
.r_dt dd ? |
.r_silence dd ? |
.resample dd ? |
.l_vol dd ? |
.r_vol dd ? |
.l_amp dw ? |
.r_amp dw ? |
.pan dd ? |
.l_amp_f dd ? ;float point left |
.r_amp_f dd ? ;float point right |
.sizeof: |
} |
FD_OFFSET equ 24 |
virtual at 0 |
STREAM STREAM |
end virtual |
struc WAVE_HEADER |
{ .riff_id dd ? |
.riff_size dd ? |
.riff_format dd ? |
.fmt_id dd ? |
.fmt_size dd ? |
.format_tag dw ? |
.channels dw ? |
.freq dd ? |
.bytes_sec dd ? |
.block_align dw ? |
.bits_sample dw ? |
.data_id dd ? |
.data_size dd ? |
} |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/drivers/audio/infinity/mix_mmx.inc |
---|
0,0 → 1,247 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; params |
; edi= output |
; eax= input stream 1 |
; ebx= input stream 2 |
if used mmx_mix_2 |
align 4 |
mmx_mix_2: |
movq mm0, [eax] |
movq mm1, [eax+8] |
movq mm2, [eax+16] |
movq mm3, [eax+24] |
movq mm4, [eax+32] |
movq mm5, [eax+40] |
movq mm6, [eax+48] |
movq mm7, [eax+56] |
paddsw mm0, [ebx] |
movq [edi], mm0 |
paddsw mm1, [ebx+8] |
movq [edi+8], mm1 |
paddsw mm2, [ebx+16] |
movq [edi+16], mm2 |
paddsw mm3, [ebx+24] |
movq [edi+24], mm3 |
paddsw mm4, [ebx+32] |
movq [edi+32], mm4 |
paddsw mm5, [ebx+40] |
movq [edi+40], mm5 |
paddsw mm6, [ebx+48] |
movq [edi+48], mm6 |
paddsw mm7, [ebx+56] |
movq [edi+56], mm7 |
movq mm0, [eax+64] |
movq mm1, [eax+72] |
movq mm2, [eax+80] |
movq mm3, [eax+88] |
movq mm4, [eax+96] |
movq mm5, [eax+104] |
movq mm6, [eax+112] |
movq mm7, [eax+120] |
paddsw mm0, [ebx+64] |
movq [edi+64], mm0 |
paddsw mm1, [ebx+72] |
movq [edi+72], mm1 |
paddsw mm2, [ebx+80] |
movq [edi+80], mm2 |
paddsw mm3, [ebx+88] |
movq [edi+88], mm3 |
paddsw mm4, [ebx+96] |
movq [edi+96], mm4 |
paddsw mm5, [ecx+104] |
movq [edx+104], mm5 |
paddsw mm6, [ebx+112] |
movq [edi+112], mm6 |
paddsw mm7, [ebx+120] |
movq [edi+120], mm7 |
ret |
align 4 |
mmx_mix_3: |
movq mm0, [eax] |
movq mm1, [eax+8] |
movq mm2, [eax+16] |
movq mm3, [eax+24] |
movq mm4, [eax+32] |
movq mm5, [eax+40] |
movq mm6, [eax+48] |
movq mm7, [eax+56] |
paddsw mm0, [ebx] |
paddsw mm1, [ebx+8] |
paddsw mm2, [ebx+16] |
paddsw mm3, [ebx+24] |
paddsw mm4, [ebx+32] |
paddsw mm5, [ebx+40] |
paddsw mm6, [ebx+48] |
paddsw mm7, [ebx+56] |
paddsw mm0, [ecx] |
movq [edi], mm0 |
paddsw mm1, [ecx+8] |
movq [edi+8], mm1 |
paddsw mm2, [ecx+16] |
movq [edi+16], mm2 |
paddsw mm3, [ecx+24] |
movq [edi+24], mm3 |
paddsw mm4, [ecx+32] |
movq [edi+32], mm4 |
paddsw mm5, [ecx+40] |
movq [edi+40], mm5 |
paddsw mm6, [ecx+48] |
movq [edi+48], mm6 |
paddsw mm7, [ecx+56] |
movq [edi+56], mm7 |
movq mm0, [eax+64] |
movq mm1, [eax+72] |
movq mm2, [eax+80] |
movq mm3, [eax+88] |
movq mm4, [eax+96] |
movq mm5, [eax+104] |
movq mm6, [eax+112] |
movq mm7, [eax+120] |
paddsw mm0, [ebx+64] |
paddsw mm1, [ebx+72] |
paddsw mm2, [ebx+80] |
paddsw mm3, [ebx+88] |
paddsw mm4, [ebx+96] |
paddsw mm5, [ebx+104] |
paddsw mm6, [ebx+112] |
paddsw mm7, [ebx+120] |
paddsw mm0, [ecx+64] |
movq [edi+64], mm0 |
paddsw mm1, [ecx+72] |
movq [edi+72], mm1 |
paddsw mm2, [ecx+80] |
movq [edi+80], mm2 |
paddsw mm3, [ecx+88] |
movq [edi+88], mm3 |
paddsw mm4, [ecx+96] |
movq [edi+96], mm4 |
paddsw mm5, [ecx+104] |
movq [edi+104], mm5 |
paddsw mm6, [ecx+112] |
movq [edi+112], mm6 |
paddsw mm7, [ecx+120] |
movq [edi+120], mm7 |
ret |
align 4 |
mmx_mix_4: |
movq mm0, [eax] |
movq mm2, [eax+8] |
movq mm4, [eax+16] |
movq mm6, [eax+24] |
movq mm1, [ebx] |
movq mm3, [ebx+8] |
movq mm5, [ebx+16] |
movq mm7, [ebx+24] |
paddsw mm0, [ecx] |
paddsw mm2, [ecx+8] |
paddsw mm4, [ecx+16] |
paddsw mm6, [ecx+24] |
paddsw mm1, [edx] |
paddsw mm3, [edx+8] |
paddsw mm5, [edx+16] |
paddsw mm7, [edx+24] |
paddsw mm0, mm1 |
movq [edi], mm0 |
paddsw mm2, mm3 |
movq [edi+8], mm2 |
paddsw mm4, mm5 |
movq [edi+16], mm4 |
paddsw mm5, mm6 |
movq [edi+24], mm6 |
movq mm0, [eax+32] |
movq mm2, [eax+40] |
movq mm4, [eax+48] |
movq mm6, [eax+56] |
movq mm1, [ebx+32] |
movq mm3, [ebx+40] |
movq mm5, [ebx+48] |
movq mm7, [ebx+56] |
paddsw mm0, [ecx+32] |
paddsw mm2, [ecx+40] |
paddsw mm4, [ecx+48] |
paddsw mm6, [ecx+56] |
paddsw mm1, [edx+32] |
paddsw mm3, [edx+40] |
paddsw mm5, [edx+48] |
paddsw mm7, [edx+56] |
paddsw mm0, mm1 |
movq [edi+32], mm0 |
paddsw mm2, mm2 |
movq [edi+40], mm2 |
paddsw mm4, mm5 |
movq [edi+48], mm4 |
paddsw mm6, mm7 |
movq [edi+56], mm6 |
movq mm0, [eax+64] |
movq mm2, [eax+72] |
movq mm4, [eax+80] |
movq mm6, [eax+88] |
movq mm1, [ebx+64] |
movq mm3, [ebx+72] |
movq mm5, [ebx+80] |
movq mm7, [ebx+88] |
paddsw mm0, [ecx+64] |
paddsw mm2, [ecx+72] |
paddsw mm4, [ecx+80] |
paddsw mm6, [ecx+88] |
paddsw mm1, [edx+64] |
paddsw mm3, [edx+72] |
paddsw mm5, [edx+80] |
paddsw mm7, [edx+88] |
paddsw mm0, mm1 |
movq [edi+64], mm0 |
paddsw mm2, mm3 |
movq [edi+72], mm2 |
paddsw mm4, mm5 |
movq [edi+80], mm4 |
paddsw mm6, mm5 |
movq [edi+88], mm7 |
movq mm0, [eax+96] |
movq mm2, [eax+104] |
movq mm4, [eax+112] |
movq mm6, [eax+120] |
movq mm1, [ebx+96] |
movq mm3, [ebx+104] |
movq mm5, [ebx+112] |
movq mm7, [ebx+120] |
paddsw mm0, [ecx+96] |
paddsw mm2, [ecx+104] |
paddsw mm4, [ecx+112] |
paddsw mm6, [ecx+120] |
paddsw mm1, [edx+96] |
paddsw mm3, [edx+104] |
paddsw mm5, [edx+112] |
paddsw mm7, [edx+120] |
paddsw mm0, mm1 |
movq [eax+96], mm0 |
paddsw mm2, mm3 |
movq [edi+104], mm2 |
paddsw mm4, mm5 |
movq [edi+112], mm4 |
paddsw mm6, mm7 |
movq [edi+120], mm6 |
ret |
end if |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/drivers/audio/infinity/mix_sse2.inc |
---|
0,0 → 1,145 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used mmx128_mix_2 |
align 4 |
mmx128_mix_2: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
movaps xmm0, [eax] |
movaps xmm1, [eax+16] |
movaps xmm2, [eax+32] |
movaps xmm3, [eax+48] |
movaps xmm4, [eax+64] |
movaps xmm5, [eax+80] |
movaps xmm6, [eax+96] |
movaps xmm7, [eax+112] |
paddsw xmm0, [ebx] |
movaps [edi], xmm0 |
paddsw xmm1, [ebx+16] |
movaps [edi+16], xmm1 |
paddsw xmm2, [ebx+32] |
movaps [edi+32], xmm2 |
paddsw xmm3, [ebx+48] |
movaps [edi+48], xmm3 |
paddsw xmm4, [ebx+64] |
movaps [edi+64], xmm4 |
paddsw xmm5, [ebx+80] |
movaps [edi+80], xmm5 |
paddsw xmm6, [ebx+96] |
movaps [edi+96], xmm6 |
paddsw xmm7, [ebx+112] |
movaps [edi+112], xmm7 |
ret |
align 4 |
mmx128_mix_3: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
prefetcht1 [ecx+128] |
movaps xmm0, [eax] |
movaps xmm1, [eax+16] |
movaps xmm2, [eax+32] |
movaps xmm3, [eax+48] |
movaps xmm4, [eax+64] |
movaps xmm5, [eax+80] |
movaps xmm6, [eax+96] |
movaps xmm7, [eax+112] |
paddsw xmm0, [ebx] |
paddsw xmm1, [ebx+16] |
paddsw xmm2, [ebx+32] |
paddsw xmm3, [ebx+48] |
paddsw xmm4, [ebx+64] |
paddsw xmm5, [ebx+80] |
paddsw xmm6, [ebx+96] |
paddsw xmm7, [ebx+112] |
paddsw xmm0, [ecx] |
movaps [edi], xmm0 |
paddsw xmm1, [ecx+16] |
movaps [edi+16], xmm1 |
paddsw xmm2, [ecx+32] |
movaps [edi+32], xmm2 |
paddsw xmm3, [ecx+48] |
movaps [edi+48], xmm3 |
paddsw xmm4, [ecx+64] |
movaps [edi+64], xmm4 |
paddsw xmm5, [ecx+80] |
movaps [edi+80], xmm5 |
paddsw xmm6, [ecx+96] |
movaps [edi+96], xmm6 |
paddsw xmm7, [ecx+112] |
movaps [edi+112], xmm7 |
ret |
align 4 |
mmx128_mix_4: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
prefetcht1 [ecx+128] |
prefetcht1 [edx+128] |
movaps xmm0, [eax] |
movaps xmm2, [eax+16] |
movaps xmm4, [eax+32] |
movaps xmm6, [eax+48] |
movaps xmm1, [ebx] |
movaps xmm3, [ebx+16] |
movaps xmm5, [ebx+32] |
movaps xmm7, [ebx+48] |
paddsw xmm0, [ecx] |
paddsw xmm2, [ecx+16] |
paddsw xmm4, [ecx+32] |
paddsw xmm6, [ecx+48] |
paddsw xmm1, [edx] |
paddsw xmm3, [edx+16] |
paddsw xmm5, [edx+32] |
paddsw xmm7, [edx+48] |
paddsw xmm0, xmm1 |
movaps [edi], xmm0 |
paddsw xmm2, xmm3 |
movaps [edi+16], xmm2 |
paddsw xmm4, xmm5 |
movaps [edi+32], xmm4 |
paddsw xmm6, xmm7 |
movaps [edi+48], xmm6 |
movaps xmm0, [eax+64] |
movaps xmm2, [eax+80] |
movaps xmm4, [eax+96] |
movaps xmm6, [eax+112] |
movaps xmm1, [ebx+64] |
movaps xmm3, [ebx+80] |
movaps xmm5, [ebx+96] |
movaps xmm7, [ebx+112] |
paddsw xmm0, [ecx+64] |
paddsw xmm2, [ecx+80] |
paddsw xmm4, [ecx+96] |
paddsw xmm6, [ecx+112] |
paddsw xmm1, [edx+64] |
paddsw xmm3, [edx+80] |
paddsw xmm5, [edx+96] |
paddsw xmm7, [edx+112] |
paddsw xmm0, xmm1 |
movaps [edi+64], xmm0 |
paddsw xmm2, xmm3 |
movaps [edi+80], xmm2 |
paddsw xmm4, xmm5 |
movaps [edi+96], xmm4 |
paddsw xmm6, xmm7 |
movaps [edi+112], xmm6 |
ret |
end if |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/drivers/audio/infinity/mixer.asm |
---|
0,0 → 1,1266 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2006-2014. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; (C) copyright Serge 2006 |
; email: infinity_sound@mail.ru |
align 4 |
mix_list rd 32*3 |
align 4 |
proc new_mix stdcall, output:dword |
locals |
main_count rd 1 |
fpu_state rb 528 ;512+16 |
endl |
mov [main_count], 32 |
call prepare_playlist |
cmp [play_count], 0 |
je .clear |
lea eax, [fpu_state+16] |
and eax, -16 ;must be 16b aligned |
invoke FpuSave |
call update_streams |
.mix: |
lea eax, [mix_list] |
call do_mix_list |
test eax, eax |
je .done |
if USE_SSE2_MIXER |
cmp eax, 1 |
ja @F |
;use fast path |
mov edi, [output] |
lea edx, [mix_list] |
call mix_fast |
jmp .next |
@@: |
cmp eax, 2 |
ja @F |
mov edi, [output] |
lea edx, [mix_list] |
call mix_fast_2_stream |
jmp .next |
@@: |
end if |
lea ebx, [mix_list] |
stdcall mix_all, [output], ebx, eax |
.next: |
add [output], 512 |
dec [main_count] |
jnz .mix |
.exit: |
lea eax, [fpu_state+16] |
and eax, -16 |
invoke FpuRestore |
ret |
.done: |
mov ecx, [main_count] |
shl ecx, 7 ;ecx*= 512/4 |
mov edi, [output] |
xor eax, eax |
cld |
rep stosd |
jmp .exit |
.clear: |
mov edi, [output] |
mov ecx, 4096 |
xor eax, eax |
cld |
rep stosd |
ret |
endp |
align 4 |
proc update_streams |
locals |
stream_index dd ? |
event rd 6 |
endl |
mov [stream_index], 0 |
.l1: |
mov edx, [stream_index] |
mov esi, [play_list+edx*4] |
add dword [esi+STREAM.time_stamp], 4096 |
adc dword [esi+STREAM.time_stamp+4], 0 |
mov dword [esi+STREAM.last_ts], 0 |
mov eax, [esi+STREAM.out_rp] |
cmp eax, [esi+STREAM.out_top] |
jb @f |
sub eax, 64*1024 |
@@: |
mov [esi+STREAM.out_rp], eax |
cmp [esi+STREAM.out_count], 16384 |
ja .skip |
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 |
endp |
align 4 |
proc refill stdcall, str:dword |
locals |
r_size rd 1 |
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 eax, [ebx+STREAM.in_count] |
test eax, eax |
jz .done |
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 |
jz .exit |
mov ebx, [ebx+STREAM.notify_id] |
mov edx, EVENT_WATCHED |
xor esi, esi |
invoke RaiseEvent ;eax, ebx, edx, esi |
.exit: |
ret |
endp |
align 4 |
proc refill_ring stdcall, str:dword |
locals |
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 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], 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, [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 |
sub eax, [ebx+STREAM.in_size] |
@@: |
mov [ebx+STREAM.in_rp], eax |
sub eax, [ebx+STREAM.in_base] |
sub eax, 128 |
lea esi, [event] |
mov dword [esi], RT_INP_EMPTY |
mov dword [esi+4], 0 |
mov dword [esi+8], ebx |
mov dword [esi+12], eax |
mov eax, [ebx+STREAM.notify_event] |
test eax, eax |
jz .exit |
mov ebx, [ebx+STREAM.notify_id] |
xor edx, edx |
invoke RaiseEvent ;eax, ebx, edx, esi |
.exit: |
ret |
endp |
if USE_SSE2_MIXER |
align 4 |
proc mix_all stdcall, dest:dword, list:dword, count:dword |
mov edi, [dest] |
mov ebx, 32 |
.mix: |
mov edx, [list] |
mov ecx, [count] |
mov eax, [edx] |
movdqa xmm1, [eax] |
movss xmm2, [edx+4] |
movss xmm3, [edx+8] |
punpcklwd xmm0, xmm1 |
punpckhwd xmm1, xmm1 |
shufps xmm2, xmm3, 0 |
shufps xmm2, xmm2, 0x88 |
psrad xmm0, 16 |
psrad xmm1, 16 |
cvtdq2ps xmm0, xmm0 |
cvtdq2ps xmm1, xmm1 |
mulps xmm0, xmm2 |
mulps xmm1, xmm2 |
.mix_loop: |
add dword [edx], 16 |
add edx, 12 |
dec ecx |
jz @F |
mov eax, [edx] |
movdqa xmm3, [eax] |
movss xmm4, [edx+4] |
movss xmm5, [edx+8] |
punpcklwd xmm2, xmm3 |
punpckhwd xmm3, xmm3 |
shufps xmm4, xmm5, 0 |
shufps xmm4, xmm4, 0x88 |
psrad xmm2, 16 |
psrad xmm3, 16 |
cvtdq2ps xmm2, xmm2 |
cvtdq2ps xmm3, xmm3 |
mulps xmm2, xmm4 |
mulps xmm3, xmm4 |
addps xmm0, xmm2 |
addps xmm1, xmm3 |
jmp .mix_loop |
@@: |
cvtps2dq xmm0, xmm0 |
cvtps2dq xmm1, xmm1 |
packssdw xmm0, xmm0 |
packssdw xmm1, xmm1 |
punpcklqdq xmm0, xmm1 |
movntdq [edi], xmm0 |
add edi, 16 |
dec ebx |
jnz .mix |
ret |
endp |
; param |
; edi = dest |
; edx = mix_list |
align 4 |
mix_fast: |
mov ebx, 32 |
mov eax, [edx] |
movss xmm2, [edx+4] ; vol Lf |
movss xmm3, [edx+8] ; vol Rf |
shufps xmm2, xmm3, 0 ; Rf Rf Lf Lf |
shufps xmm2, xmm2, 0x88 ; volume level Rf Lf Rf Lf |
.mix: |
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w |
add eax, 16 |
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w |
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w |
psrad xmm0, 16 ; R1d L1d R0d L0d |
psrad xmm1, 16 ; R3d L3d R2d L2d |
cvtdq2ps xmm0, xmm0 ; time to use all power |
cvtdq2ps xmm1, xmm1 ; of the dark side |
mulps xmm0, xmm2 ; R1f' L1f' R0f' L0f' |
mulps xmm1, xmm2 ; R3f' L3f' R2f' L2f' |
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d' |
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d' |
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w' |
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w' |
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w' |
movntdq [edi], xmm0 |
add edi, 16 |
dec ebx |
jnz .mix |
ret |
align 4 |
mix_fast_2_stream: |
mov ebx, 32 |
mov eax, [edx] |
movss xmm4, [edx+4] ; vol Lf |
movss xmm5, [edx+8] ; vol Rf |
mov ecx, [edx+12] |
movss xmm6, [edx+16] ; vol Lf |
movss xmm7, [edx+20] ; vol Rf |
shufps xmm4, xmm5, 0 ; Rf Rf Lf Lf |
shufps xmm4, xmm4, 0x88 ; volume level Rf Lf Rf Lf |
shufps xmm6, xmm7, 0 ; Rf Rf Lf Lf |
shufps xmm6, xmm6, 0x88 ; volume level Rf Lf Rf Lf |
.mix: |
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w |
movdqa xmm3, [ecx] ; R3w L3w R2w L2w R1w L1w R0w L0w |
add eax, 16 |
add ecx, 16 |
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w |
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w |
psrad xmm0, 16 ; R1d L1d R0d L0d |
psrad xmm1, 16 ; R3d L3d R2d L2d |
cvtdq2ps xmm0, xmm0 ; time to use all power |
cvtdq2ps xmm1, xmm1 ; of the dark side |
mulps xmm0, xmm4 ; R1f' L1f' R0f' L0f' |
mulps xmm1, xmm4 ; R3f' L3f' R2f' L2f' |
punpcklwd xmm2, xmm3 ; R1w R1w L1w L1W R0w R0w L0w L0w |
punpckhwd xmm3, xmm3 ; R3w R3w L3w L3w R2w R2w L2w L2w |
psrad xmm2, 16 ; R1d L1d R0d L0d |
psrad xmm3, 16 ; R3d L3d R2d L2d |
cvtdq2ps xmm2, xmm2 ; time to use all power |
cvtdq2ps xmm3, xmm3 ; of the dark side |
mulps xmm2, xmm6 ; R1f' L1f' R0f' L0f' |
mulps xmm3, xmm6 ; R3f' L3f' R2f' L2f' |
addps xmm0, xmm2 |
addps xmm1, xmm3 |
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d' |
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d' |
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w' |
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w' |
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w' |
movntdq [edi], xmm0 |
add edi, 16 |
dec ebx |
jnz .mix |
ret |
else ; fixed point mmx version |
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, 12 |
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 |
@@: |
movq [edi], mm0 |
add edi, 8 |
dec ebx |
jnz .mix |
ret |
endp |
end if |
align 4 |
proc resample_1 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
; dest equ esp+8 |
; src equ esp+12 |
; r_dt equ esp+16 |
; r_size equ esp+20 |
; r_end equ esp+24 |
mov edi, [dest] |
mov edx, [src] |
sub edx, 32*2 |
mov eax, 16 |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*2] |
movsx ebp, word [esi] |
movsx esi, word [esi+2] |
mov ebx, 32768 |
imul esi, ecx |
sub ebx, ecx |
imul ebx, ebp |
lea ecx, [ebx+esi+16384] |
sar ecx, 15 |
cmp ecx, 32767 ; 00007fffH |
jle @f |
mov ecx, 32767 ; 00007fffH |
jmp .write |
@@: |
cmp ecx, -32768 ; ffff8000H |
jge .write |
mov ecx, -32768 ; ffff8000H |
.write: |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
mov [edi], ebx |
add edi, 4 |
add eax, [esp+16] |
cmp eax, [esp+24] |
jb .l1 |
mov ebp, esp |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc resample_18 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edi, [dest] |
mov edx, [src] |
sub edx, 32 |
mov esi, 16 |
align 4 |
.l1: |
mov ecx, esi |
mov eax, esi |
and ecx, 0x7FFF |
shr eax, 15 |
lea eax, [edx+eax] |
mov bx, word [eax] |
sub bh, 0x80 |
sub bl, 0x80 |
movsx eax, bh |
shl eax, 8 |
movsx ebp, bl |
shl ebp, 8 |
mov ebx, 32768 |
imul eax, ecx |
sub ebx, ecx |
imul ebx, ebp |
lea ecx, [ebx+eax+16384] |
sar ecx, 15 |
cmp ecx, 32767 ; 00007fffH |
jle @f |
mov ecx, 32767 ; 00007fffH |
jmp .write |
@@: |
cmp ecx, -32768 ; ffff8000H |
jge .write |
mov ecx, -32768 ; ffff8000H |
.write: |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
mov [edi], ebx |
add edi, 4 |
add esi, [esp+16] |
cmp esi, [esp+24] |
jb .l1 |
mov ebp, esp |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc copy_stream stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov ecx, [r_size] |
mov eax, ecx |
shr ecx, 2 |
mov esi, [src] |
mov edi, [dest] |
cld |
rep movsd |
ret |
endp |
align 4 |
proc resample_2 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edx, [src] |
sub edx, 32*4 |
mov edi, [dest] |
mov ebx, [r_dt] |
mov eax, 16 |
emms |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*4] |
movq mm0, [esi] |
movq mm1, mm0 |
movd mm2, ecx |
punpcklwd mm2, mm2 |
movq mm3, qword [m7] ;0x8000 |
psubw mm3, mm2 ; ;0x8000 - iconst |
punpckldq mm3, mm2 |
pmulhw mm0, mm3 |
pmullw mm1, mm3 |
movq mm4, mm1 |
punpcklwd mm1, mm0 |
punpckhwd mm4, mm0 |
paddd mm1, mm4 |
psrad mm1, 15 |
packssdw mm1, mm1 |
movd [edi], mm1 |
add edi, 4 |
add eax, ebx |
cmp eax, [r_end] |
jb .l1 |
emms |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc resample_28 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edx, [src] |
sub edx, 32*2 |
mov edi, [dest] |
mov ebx, [r_dt] |
mov eax, 16 |
emms |
movq mm7, [mm80] |
movq mm6, [mm_mask] |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*2] |
movq mm0, [esi] |
psubb mm0, mm7 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
movq mm1, mm0 |
movd mm2, ecx |
punpcklwd mm2, mm2 |
movq mm3, qword [m7] ; // 0x8000 |
psubw mm3, mm2 ; // 0x8000 - iconst |
punpckldq mm3, mm2 |
pmulhw mm0, mm3 |
pmullw mm1, mm3 |
movq mm4, mm1 |
punpcklwd mm1, mm0 |
punpckhwd mm4, mm0 |
paddd mm1, mm4 |
psrad mm1, 15 |
packssdw mm1, mm1 |
movd [edi], mm1 |
add edi, 4 |
add eax, ebx |
cmp eax, [r_end] |
jb .l1 |
emms |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
proc m16_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx, 8 |
@@: |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
ret |
endp |
align 4 |
proc s8_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx, 7 |
movq mm7, [mm80] |
movq mm6, [mm_mask] |
@@: |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
ret |
endp |
proc m8_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx, 6 |
movq mm7, [mm80] |
movq mm6, [mm_mask] |
@@: |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
add eax, eax |
ret |
endp |
align 4 |
proc alloc_mix_buff |
bsf eax, [mix_buff_map] |
jnz .find |
xor eax, eax |
ret |
.find: |
btr [mix_buff_map], eax |
shl eax, 9 |
add eax, [mix_buff] |
ret |
endp |
align 4 |
proc m16_s_mmx |
movq mm0, [esi] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi], mm0 |
movq [edi+8], mm1 |
movq mm0, [esi+8] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+16], mm0 |
movq [edi+24], mm1 |
movq mm0, [esi+16] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+32], mm0 |
movq [edi+40], mm1 |
movq mm0, [esi+24] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+48], mm0 |
movq [edi+56], mm1 |
movq mm0, [esi+32] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+64], mm0 |
movq [edi+72], mm1 |
movq mm0, [esi+40] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+80], mm0 |
movq [edi+88], mm1 |
movq mm0, [esi+48] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+96], mm0 |
movq [edi+104], mm1 |
movq mm0, [esi+56] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+112], mm0 |
movq [edi+120], mm1 |
ret |
endp |
align 4 |
proc s8_s_mmx |
movq mm0, [esi] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi], mm0 |
movq [edi+8], mm1 |
movq mm0, [esi+8] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+16], mm0 |
movq [edi+24], mm1 |
movq mm0, [esi+16] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+32], mm0 |
movq [edi+40], mm1 |
movq mm0, [esi+24] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+48], mm0 |
movq [edi+56], mm1 |
ret |
endp |
align 4 |
proc m8_s_mmx |
movq mm0, [esi] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq mm2, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm2, mm2 |
movq mm3, mm1 |
punpcklwd mm1, mm1 |
punpckhwd mm3, mm3 |
movq [edi], mm0 |
movq [edi+8], mm2 |
movq [edi+16], mm1 |
movq [edi+24], mm3 |
movq mm0, [esi+8] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq mm2, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm2, mm2 |
movq mm3, mm1 |
punpcklwd mm1, mm1 |
punpckhwd mm3, mm3 |
movq [edi+32], mm0 |
movq [edi+40], mm2 |
movq [edi+48], mm1 |
movq [edi+56], mm3 |
ret |
endp |
align 4 |
proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov esi, 128 |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
ret |
endp |
align 4 |
proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov esi, 128 |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
ret |
endp |
align 4 |
proc mix_4_1 stdcall, str0:dword, str1:dword,\ |
str2:dword, str3:dword |
local output:DWORD |
call alloc_mix_buff |
and eax, eax |
jz .err |
mov [output], eax |
mov edi, eax |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov edx, [str3] |
mov esi, 128 |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
mov eax, [output] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc final_mix stdcall, output:dword, str0:dword, str1:dword,\ |
str2:dword, str3:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov edx, [str3] |
mov esi, 128 |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
ret |
endp |
align 4 |
proc copy_mem stdcall, output:dword, input:dword |
mov edi, [output] |
mov esi, [input] |
mov ecx, 0x80 |
.l1: |
mov eax, [esi] |
mov [edi], eax |
add esi, 4 |
add edi, 4 |
loop .l1 |
ret |
endp |
proc memcpy |
@@: |
mov eax, [esi] |
mov [edi], eax |
add esi, 4 |
add edi, 4 |
dec ecx |
jnz @B |
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 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:keywords |
+Rev |
\ No newline at end of property |