0,0 → 1,571 |
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 ; ñòêóêòóðà ñîáûòèÿ îò äðàéâåðà |