d24c668030
git-svn-id: svn://kolibrios.org@4323 a494cfbc-eb01-0410-851d-a64ba20cac60
571 lines
12 KiB
PHP
571 lines
12 KiB
PHP
SSMIX_CHANMODE_FREE equ 0
|
|
SSMIX_CHANMODE_SINGLE equ 1
|
|
SSMIX_CHANMODE_REPEAT equ 2
|
|
SSMIX_CHANMODE_SINGLE_WITHOUT_RESET equ 3
|
|
SSMIX_CHANMODE_WAITRESET equ 4
|
|
|
|
include 'snd.inc'
|
|
include 'snd_const.inc'
|
|
include 'proc32.inc'
|
|
;include 'macros.inc'
|
|
;include 'debug.inc'
|
|
|
|
SSMIX_CHANNEL_COUNT equ 32
|
|
|
|
DEBUG equ 0 ; 0
|
|
|
|
|
|
; èíèöèàëèçàöèÿ ìèêøåðà
|
|
ssmix_init:
|
|
; âûäåëèòü ïàìÿòü äëÿ êàíàëîâ ìèêøåðà
|
|
mov eax, 68
|
|
mov ebx, 12
|
|
mov ecx, 4*8*SSMIX_CHANNEL_COUNT
|
|
int 0x40
|
|
mov [ssmix_channels], eax
|
|
; âûäåëèòü ïàìÿòü äëÿ ñòåêà ïîòîêà ìèêøåðà
|
|
mov eax, 68
|
|
mov ebx, 12
|
|
mov ecx, 4096
|
|
int 0x40
|
|
mov [ssmix_thread_stack], eax
|
|
; âêëþ÷èòü ìèêøåð
|
|
mov [ssmix_state], 1
|
|
; óñòàíîâèòü ãðîìêîñòè ñòåðåîêàíàëîâ
|
|
mov [ssmix_volumeL], 128
|
|
mov [ssmix_volumeR], 128
|
|
; ñîçäàòü ïîòîê
|
|
mov eax, 51
|
|
mov ebx, 1
|
|
mov ecx, ssmix_thread_proc
|
|
mov edx,[ssmix_thread_stack]
|
|
add edx,4092
|
|
int 0x40
|
|
|
|
ret
|
|
|
|
|
|
|
|
; çàâåðøåíèå ðàáîòû ìèêøåðà
|
|
ssmix_release:
|
|
; âûêëþ÷èòü ìèêøåð
|
|
mov [ssmix_state], 0
|
|
|
|
ret
|
|
|
|
|
|
|
|
; îñâîáîæäåíèå ïàìÿòè
|
|
ssmix_free:
|
|
; îñâîáîäèòü ïàìÿòü êàíàëîâ ìèêøåðà
|
|
mov eax, 68
|
|
mov ebx, 13
|
|
mov ecx, [ssmix_channels]
|
|
int 0x40
|
|
; îñâîáîäèòü ïàìÿòü ñòåêà ïîòîêà ìèêøåðà
|
|
mov eax, 68
|
|
mov ebx, 13
|
|
mov ecx, [ssmix_thread_stack]
|
|
int 0x40
|
|
|
|
ret
|
|
|
|
; óñòàíîâèòü ãðîìêîñòü
|
|
ssmix_setvolume: ; stdcall
|
|
; LeftVolume: dword, RightVolume: dword
|
|
|
|
push eax
|
|
mov eax, [esp+8] ; ãðîìêîñòü ëåâîãî êàíàëà
|
|
cmp eax, 255
|
|
jle @f
|
|
mov eax, 255
|
|
@@:
|
|
cmp eax, 0
|
|
jge @f
|
|
mov eax, 0
|
|
@@:
|
|
mov [ssmix_volumeL], eax
|
|
|
|
mov eax, [esp+12] ; ãðîìêîñòü ïðàâîãî êàíàëà
|
|
cmp eax, 255
|
|
jle @f
|
|
mov eax, 255
|
|
@@:
|
|
cmp eax, 0
|
|
jge @f
|
|
mov eax, 0
|
|
@@:
|
|
mov [ssmix_volumeR], eax
|
|
pop eax
|
|
|
|
ret
|
|
|
|
|
|
; âîñïðîèçâåñòè òðåê
|
|
ssmix_playtrack: ; stdcall
|
|
; p_starttrack:dword, p_endtrack:dword, volumeL: dword, volumeR: dword; playmode:dword;
|
|
; return eax - number of channel, if eax=-1 then no free channel
|
|
|
|
push ebx ecx
|
|
mov ebx, [ssmix_channels]
|
|
mov ecx, SSMIX_CHANNEL_COUNT
|
|
.channel_loop:
|
|
mov eax, [ebx]
|
|
cmp eax, SSMIX_CHANMODE_FREE
|
|
je .find_free_channel
|
|
add ebx, 32
|
|
dec ecx
|
|
jnz .channel_loop
|
|
mov eax, -1
|
|
jmp .end
|
|
.find_free_channel:
|
|
mov eax, [esp+28] ; ðåæèì âîñïðîèçâåäåíèÿ
|
|
mov [ebx], eax
|
|
mov eax, [esp+20] ; ãðîìêîñòü ëåâîãî êàíàëà
|
|
imul eax, [ssmix_volumeL]
|
|
sar eax, 7
|
|
mov [ebx+4], eax
|
|
mov eax, [esp+24] ; ãðîìêîñòü ïðàâîãî êàíàëà
|
|
imul eax, [ssmix_volumeR]
|
|
sar eax, 7
|
|
mov [ebx+8], eax
|
|
mov eax, [esp+12] ; íà÷àëî òðåêà
|
|
mov [ebx+16], eax
|
|
mov [ebx+20], eax
|
|
mov eax, [esp+16] ; êîíåö òðåêà
|
|
mov [ebx+24], eax
|
|
mov eax, SSMIX_CHANNEL_COUNT
|
|
sub eax, ecx
|
|
.end:
|
|
pop ecx ebx
|
|
|
|
ret 20
|
|
|
|
|
|
; îñòàíîâèòü òðåê ïî íîìåðó êàíàëà
|
|
ssmix_stoptrack: ; stdcall
|
|
; numchannel: dword
|
|
push eax ebx
|
|
mov ebx, [esp+12]
|
|
cmp ebx, 0
|
|
jl .end
|
|
cmp ebx, SSMIX_CHANNEL_COUNT
|
|
jge .end
|
|
shl ebx, 5
|
|
add ebx, [ssmix_channels]
|
|
mov eax, SSMIX_CHANMODE_FREE
|
|
mov [ebx], eax
|
|
.end:
|
|
pop ebx eax
|
|
|
|
ret 4
|
|
|
|
|
|
; îñòàíîâèòü âñå òðåêè
|
|
ssmix_stopalltracks:
|
|
|
|
push eax ebx ecx
|
|
mov eax, SSMIX_CHANMODE_FREE
|
|
mov ebx, [ssmix_channels]
|
|
mov ecx, SSMIX_CHANNEL_COUNT
|
|
.channel_loop:
|
|
mov [ebx], eax
|
|
add ebx, 32
|
|
dec ecx
|
|
jnz .channel_loop
|
|
pop ecx ebx eax
|
|
|
|
ret
|
|
|
|
|
|
; ïîòîê ìèêøåðà
|
|
ssmix_thread_proc:
|
|
|
|
stdcall _InitSound@4, ssmix_driver_version
|
|
test eax, eax
|
|
jz @f
|
|
if DEBUG
|
|
print "ssmix. Cannot load sound driver"
|
|
end if
|
|
jmp .end
|
|
@@:
|
|
|
|
mov ecx, [ssmix_driver_version]
|
|
cmp cx, SOUND_VERSION
|
|
jae @f
|
|
shr ecx, 16
|
|
cmp ecx, SOUND_VERSION
|
|
jbe @f
|
|
if DEBUG
|
|
print "ssmix. Sound version mismatch"
|
|
end if
|
|
jmp .end
|
|
@@:
|
|
|
|
stdcall _CreateBuffer@12, PCM_2_16_11+PCM_RING, 0, ssmix_hbuffer
|
|
test eax, eax
|
|
jz @f
|
|
if DEBUG
|
|
print "ssmix. create buffer error"
|
|
end if
|
|
jmp .end
|
|
@@:
|
|
|
|
stdcall _GetBufferSize@8, [ssmix_hbuffer], ssmix_buffer_size
|
|
test eax, eax
|
|
jz @f
|
|
if DEBUG
|
|
print "ssmix. getbuffersize procedure error"
|
|
end if
|
|
jmp .destroy_buffer
|
|
@@:
|
|
|
|
mov ecx, [ssmix_buffer_size]
|
|
shr ecx, 1
|
|
mov [ssmix_buffer_size], ecx
|
|
if DEBUG
|
|
print "ssmix. buffer size"
|
|
dph ecx
|
|
newline
|
|
end if
|
|
|
|
; âûäåëèòü ïàìÿòü äëÿ áóôôåðà âîñïðîèçâåäåíèÿ
|
|
mov eax, 68
|
|
mov ebx, 12
|
|
mov ecx, [ssmix_buffer_size]
|
|
int 0x40
|
|
test eax, eax
|
|
jnz @f
|
|
if DEBUG
|
|
print "ssmix. malloc memory error"
|
|
end if
|
|
jmp .destroy_buffer
|
|
@@:
|
|
mov [ssmix_pbuffer], eax
|
|
|
|
stdcall _PlayBuffer@8, [ssmix_hbuffer], 0
|
|
test eax, eax
|
|
jz @f
|
|
if DEBUG
|
|
print "ssmix. playbuffer error"
|
|
end if
|
|
jmp .free_buffer_memory
|
|
@@:
|
|
|
|
; öèêë âîñïðîèçâåäåíèÿ
|
|
.mixloop:
|
|
; ïîëó÷èòü äàííûå ñîáûòèÿ îò äðàéâåðà
|
|
mov eax, 68
|
|
mov ebx, 14
|
|
mov ecx, ssmix_driver_notify_struct
|
|
int 0x40
|
|
; ïðîâåðêà íà code
|
|
mov eax, [ssmix_driver_notify_struct]
|
|
cmp eax, 0xFF000001
|
|
jne .mixloop
|
|
; ïðîâåðêà íà stream
|
|
mov eax, [ssmix_driver_notify_struct+8]
|
|
cmp eax, [ssmix_hbuffer]
|
|
jne .mixloop
|
|
; ïîëó÷èòü ñìåùåíèå â áóôôåðå
|
|
mov eax, [ssmix_driver_notify_struct+12]
|
|
mov [ssmix_buffer_offset], eax
|
|
; öèêë çàïîëíåíèÿ áóôôåðà
|
|
mov ebx, [ssmix_pbuffer]
|
|
mov ecx, [ssmix_buffer_size]
|
|
shr ecx, 2
|
|
.fill_buffer_loop:
|
|
push ebx ecx
|
|
; öèêë ñìåøèâàíèÿ êàíàëîâ
|
|
mov esi, 0 ; ñóììà äëÿ ëåâîãî ñòåðåîêàíàëà
|
|
mov edi, 0 ; ñóììà äëÿ ïðàâîãî ñòåðåîêàíàëà
|
|
mov edx, [ssmix_channels]
|
|
mov ecx, SSMIX_CHANNEL_COUNT
|
|
.channel_loop:
|
|
mov eax, [edx]
|
|
cmp eax, SSMIX_CHANMODE_FREE
|
|
je .channel_end
|
|
cmp eax, SSMIX_CHANMODE_WAITRESET
|
|
je .channel_end
|
|
push ecx
|
|
; ñìåøèâàíèå êàíàëîâ ñ ó÷åòîì ãðîìêîñòè
|
|
mov ebx, [edx+4]
|
|
mov ecx, [edx+16]
|
|
movsx eax, word [ecx]
|
|
imul eax, ebx
|
|
add esi, eax
|
|
mov ebx, [edx+8]
|
|
movsx eax, word [ecx+2]
|
|
imul eax, ebx
|
|
add edi, eax
|
|
; ïðîâåðêà íà çàâåðøåíèå òðåêà
|
|
add ecx, 4
|
|
cmp ecx, [edx+24]
|
|
jb .notrackend
|
|
mov eax, [edx]
|
|
cmp eax, SSMIX_CHANMODE_SINGLE
|
|
jne @f
|
|
mov ebx, SSMIX_CHANMODE_FREE
|
|
mov [edx], ebx
|
|
jmp .notrackend
|
|
@@:
|
|
cmp eax, SSMIX_CHANMODE_REPEAT
|
|
jne @f
|
|
mov ecx, [edx+20]
|
|
jmp .notrackend
|
|
@@:
|
|
cmp eax, SSMIX_CHANMODE_SINGLE_WITHOUT_RESET
|
|
jne @f
|
|
mov ebx, SSMIX_CHANMODE_WAITRESET
|
|
mov [edx], ebx
|
|
jmp .notrackend
|
|
@@:
|
|
.notrackend:
|
|
mov [edx+16], ecx
|
|
pop ecx
|
|
.channel_end:
|
|
add edx, 32
|
|
dec ecx
|
|
jnz .channel_loop
|
|
; íîðìàëèçàöèÿ ñòåðåîêàíàëîâ
|
|
sar esi, 7
|
|
cmp esi, 0x7FFF
|
|
jle @f
|
|
mov esi, 0x7FFF
|
|
@@:
|
|
cmp esi, -0x8000
|
|
jge @f
|
|
mov esi, -0x8000
|
|
@@:
|
|
sar edi, 7
|
|
cmp edi, 0x7FFF
|
|
jle @f
|
|
mov edi, 0x7FFF
|
|
@@:
|
|
cmp edi, -0x8000
|
|
jge @f
|
|
mov edi, -0x8000
|
|
@@:
|
|
; ñîõðàíåíèå ðåçóëüòàòà â áóôôåðå ìèêøåðà
|
|
shl edi, 16
|
|
add esi, edi
|
|
pop ecx ebx
|
|
mov [ebx], esi
|
|
add ebx, 4
|
|
dec ecx
|
|
jnz .fill_buffer_loop
|
|
; óñòàíîâêà áóôôåðà äðàéâåðà
|
|
stdcall _SetBuffer@16, [ssmix_hbuffer], [ssmix_pbuffer], [ssmix_buffer_offset], [ssmix_buffer_size]
|
|
cmp [ssmix_state], 1
|
|
je .mixloop
|
|
|
|
; îñâîáîäèòü ïàìÿòü áóôôåðà âîñïðîèçâåäåíèÿ
|
|
.free_buffer_memory:
|
|
mov eax, 68
|
|
mov ebx, 13
|
|
mov ecx, [ssmix_pbuffer]
|
|
; óíè÷òîæèòü áóôôåð äðàéâåðà
|
|
.destroy_buffer:
|
|
stdcall _DestroyBuffer@4, [ssmix_hbuffer]
|
|
|
|
; çàâåðøèòü ðàáîòó ïîòîêà
|
|
.end:
|
|
call ssmix_free
|
|
mov eax, -1
|
|
int 0x40
|
|
|
|
;ret
|
|
|
|
|
|
;=================================================================================
|
|
|
|
align 4
|
|
_InitSound@4: ;p_ver:dword
|
|
|
|
push ebx
|
|
push ecx
|
|
|
|
mov eax, 68
|
|
mov ebx, 16
|
|
mov ecx, ssmix_szInfinity
|
|
int 0x40
|
|
mov [ssmix_hSound], eax
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
mov eax, 68
|
|
mov ebx, 16
|
|
mov ecx, ssmix_szSound
|
|
int 0x40
|
|
mov [ssmix_hrdwSound], eax
|
|
|
|
lea eax, [esp+12] ;p_ver
|
|
xor ebx, ebx
|
|
|
|
push 4 ;.out_size
|
|
push eax ;.output
|
|
push ebx ;.inp_size
|
|
push ebx ;.input
|
|
push SRV_GETVERSION ;.code
|
|
push [ssmix_hSound] ;.handle
|
|
|
|
mov eax, 68
|
|
mov ebx, 17
|
|
mov ecx, esp ;[handle]
|
|
int 0x40
|
|
add esp, 24
|
|
pop ecx
|
|
pop ebx
|
|
ret 4
|
|
.fail:
|
|
or eax, -1
|
|
pop ecx
|
|
pop ebx
|
|
ret 4
|
|
|
|
|
|
align 4
|
|
_CreateBuffer@12: ;format:dword,size:dword,p_str:dword
|
|
|
|
push ebx
|
|
push ecx
|
|
lea eax, [esp+20] ;p_str
|
|
lea ebx, [esp+12] ;format
|
|
|
|
push 4 ;.out_size
|
|
push eax ;.output
|
|
push 8 ;.inp_size
|
|
push ebx ;.input
|
|
push SND_CREATE_BUFF;.code
|
|
push [ssmix_hSound] ;.handle
|
|
|
|
mov eax, 68
|
|
mov ebx, 17
|
|
mov ecx, esp
|
|
int 0x40
|
|
add esp, 24 ;io_cintrol
|
|
pop ecx
|
|
pop ebx
|
|
ret 12
|
|
|
|
align 4
|
|
_DestroyBuffer@4: ;str:dword
|
|
|
|
push ebx
|
|
push ecx
|
|
|
|
xor eax, eax
|
|
lea ebx, [esp+12] ;[stream]
|
|
|
|
push eax ;.out_size
|
|
push eax ;.output
|
|
push 4 ;.inp_size
|
|
push ebx ;.input
|
|
push SND_DESTROY_BUFF;.code
|
|
push [ssmix_hSound] ;.handle
|
|
|
|
mov eax, 68
|
|
mov ebx, 17
|
|
mov ecx, esp ;[handle]
|
|
int 0x40
|
|
add esp, 24
|
|
pop ecx
|
|
pop ebx
|
|
ret 4
|
|
|
|
align 4
|
|
_GetBufferSize@8: ;str:dword, p_size:dword
|
|
|
|
push ebx
|
|
push ecx
|
|
|
|
lea eax, [esp+16]
|
|
lea ebx, [esp+12] ;[stream]
|
|
|
|
push 4 ;.out_size
|
|
push eax ;.output
|
|
push 4 ;.inp_size
|
|
push ebx ;.input
|
|
push SND_GETBUFFSIZE;.code
|
|
push dword [ssmix_hSound] ;.handle
|
|
|
|
mov eax, 68
|
|
mov ebx, 17
|
|
mov ecx, esp
|
|
int 0x40
|
|
add esp, 24
|
|
pop ecx
|
|
pop ebx
|
|
ret 8
|
|
|
|
align 4
|
|
_SetBuffer@16: ;str:dword, src:dword, offs:dword, size:dword
|
|
|
|
push ebx
|
|
push ecx
|
|
|
|
xor eax, eax
|
|
lea ebx, [esp+12] ;[stream]
|
|
|
|
push eax ;.out_size
|
|
push eax ;.output
|
|
push 16 ;.inp_size
|
|
push ebx ;.input
|
|
push SND_SETBUFF ;.code
|
|
push dword [ssmix_hSound] ;.handle
|
|
|
|
mov eax, 68
|
|
mov ebx, 17
|
|
mov ecx, esp
|
|
int 0x40
|
|
add esp, 24
|
|
pop ecx
|
|
pop ebx
|
|
ret 16
|
|
|
|
align 4
|
|
_PlayBuffer@8: ;str:dword,flags:dword
|
|
|
|
push ebx
|
|
push ecx
|
|
|
|
xor eax, eax
|
|
lea ebx, [esp+12] ;[stream]
|
|
|
|
push eax ;.out_size
|
|
push eax ;.output
|
|
push 8 ;.inp_size
|
|
push ebx ;.input
|
|
push SND_PLAY ;.code
|
|
push dword [ssmix_hSound] ;.handle
|
|
|
|
mov eax, 68
|
|
mov ebx, 17
|
|
mov ecx, esp
|
|
int 0x40
|
|
add esp, 24
|
|
pop ecx
|
|
pop ebx
|
|
ret 8
|
|
|
|
|
|
|
|
; ========================= data =====================================
|
|
|
|
ssmix_hSound dd ?
|
|
ssmix_hrdwSound dd ?
|
|
|
|
ssmix_szInfinity db 'INFINITY',0
|
|
ssmix_szSound db 'SOUND',0
|
|
|
|
ssmix_channels dd 0
|
|
ssmix_thread_stack dd 0
|
|
ssmix_state dd 0
|
|
ssmix_volumeL dd ?
|
|
ssmix_volumeR dd ?
|
|
ssmix_driver_version dd ?
|
|
ssmix_hbuffer dd ?
|
|
ssmix_pbuffer dd 0
|
|
ssmix_buffer_size dd ?
|
|
ssmix_buffer_offset dd ?
|
|
ssmix_driver_notify_struct rd 6 ; ñòêóêòóðà ñîáûòèÿ îò äðàéâåðà |