forked from KolibriOS/kolibrios
15170454cc
kernel objects segmented sound buffers git-svn-id: svn://kolibrios.org@281 a494cfbc-eb01-0410-851d-a64ba20cac60
753 lines
18 KiB
NASM
753 lines
18 KiB
NASM
;
|
|
; This file is part of the Infinity sound library.
|
|
; (C) copyright Serge 2006
|
|
; email: infinity_sound@mail.ru
|
|
;
|
|
; This program is free software; you can redistribute it and/or modify
|
|
; it under the terms of the GNU General Public License as published by
|
|
; the Free Software Foundation; either version 2 of the License, or
|
|
; (at your option) any later version.
|
|
;
|
|
; This program is distributed in the hope that it will be useful,
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
; GNU General Public License for more details.
|
|
|
|
format MS COFF
|
|
|
|
include 'proc32.inc'
|
|
include 'main.inc'
|
|
include 'imports.inc'
|
|
|
|
DEBUG equ 1
|
|
|
|
EVENT_NOTIFY equ 0x00000200
|
|
|
|
OS_BASE equ 0; 0x80400000
|
|
new_app_base equ 0x60400000; 0x01000000
|
|
PROC_BASE equ OS_BASE+0x0080000
|
|
|
|
public START
|
|
public service_proc
|
|
public version
|
|
|
|
SND_CREATE_BUFF equ 2
|
|
SND_PLAY equ 3
|
|
SND_STOP equ 4
|
|
SND_SETBUFF equ 5
|
|
SND_DESTROY_BUFF equ 6
|
|
|
|
DEV_PLAY equ 1
|
|
DEV_STOP equ 2
|
|
DEV_CALLBACK equ 3
|
|
|
|
struc IOCTL
|
|
{ .handle dd ?
|
|
.io_code dd ?
|
|
.input dd ?
|
|
.inp_size dd ?
|
|
.output dd ?
|
|
.out_size dd ?
|
|
}
|
|
|
|
virtual at 0
|
|
IOCTL IOCTL
|
|
end virtual
|
|
|
|
section '.flat' code readable align 16
|
|
|
|
proc START stdcall, state:dword
|
|
|
|
cmp [state], 1
|
|
jne .exit
|
|
|
|
stdcall GetService, szSound
|
|
test eax, eax
|
|
jz .fail
|
|
mov [hSound], eax
|
|
|
|
stdcall KernelAlloc, 16*512
|
|
test eax, eax
|
|
jz .out_of_mem
|
|
mov [mix_buff], eax
|
|
|
|
mov edi, stream_list
|
|
mov ecx, 17
|
|
xor eax, eax
|
|
cld
|
|
rep stosd
|
|
|
|
mov edi, stream
|
|
mov ecx, 4*STREAM_SIZE
|
|
rep stosd
|
|
mov [stream_count],0
|
|
|
|
stdcall set_handler, [hSound], new_mix
|
|
stdcall RegService, szInfinity, service_proc
|
|
ret
|
|
.fail:
|
|
if DEBUG
|
|
mov esi, msgFail
|
|
call SysMsgBoardStr
|
|
end if
|
|
.exit:
|
|
xor eax, eax
|
|
ret
|
|
|
|
.out_of_mem:
|
|
if DEBUG
|
|
mov esi, msgMem
|
|
call SysMsgBoardStr
|
|
end if
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
handle equ IOCTL.handle
|
|
io_code equ IOCTL.io_code
|
|
input equ IOCTL.input
|
|
inp_size equ IOCTL.inp_size
|
|
output equ IOCTL.output
|
|
out_size equ IOCTL.out_size
|
|
|
|
align 4
|
|
proc service_proc stdcall, ioctl:dword
|
|
|
|
mov edi, [ioctl]
|
|
mov eax, [edi+io_code]
|
|
|
|
cmp eax, SND_CREATE_BUFF
|
|
jne @F
|
|
mov ebx, [edi+input]
|
|
stdcall CreateBuffer,[ebx]
|
|
ret
|
|
@@:
|
|
cmp eax, SND_PLAY
|
|
jne @F
|
|
|
|
mov ebx, [edi+input]
|
|
stdcall play_buffer, [ebx]
|
|
ret
|
|
@@:
|
|
cmp eax, SND_STOP
|
|
jne @F
|
|
|
|
; if DEBUG
|
|
; mov esi, msgStop
|
|
; call [SysMsgBoardStr]
|
|
; end if
|
|
|
|
mov ebx, [edi+input]
|
|
stdcall stop_buffer, [ebx]
|
|
ret
|
|
@@:
|
|
cmp eax, SND_SETBUFF
|
|
jne @F
|
|
|
|
mov ebx, [edi+input]
|
|
mov eax, [ebx+4]
|
|
add eax, new_app_base
|
|
stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12]
|
|
ret
|
|
@@:
|
|
cmp eax, SND_DESTROY_BUFF
|
|
jne @F
|
|
|
|
mov ebx, [edi+input]
|
|
stdcall DestroyBuffer, [ebx]
|
|
ret
|
|
@@:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
restore handle
|
|
restore io_code
|
|
restore input
|
|
restore inp_size
|
|
restore output
|
|
restore out_size
|
|
|
|
TASK_COUNT equ 0x0003004
|
|
CURRENT_TASK equ 0x0003000
|
|
|
|
align 8
|
|
proc CreateBuffer stdcall, format:dword
|
|
locals
|
|
str dd ?
|
|
endl
|
|
|
|
call alloc_stream
|
|
and eax, eax
|
|
jz .fail
|
|
mov [str], eax
|
|
mov edi, eax
|
|
|
|
mov edx, [stream_count]
|
|
mov [stream_list+edx*4], eax
|
|
inc [stream_count]
|
|
|
|
mov [edi+STREAM.magic], 'WAVE'
|
|
mov [edi+STREAM.size], STREAM_SIZE
|
|
|
|
stdcall KernelAlloc, 180*1024
|
|
|
|
mov edi, [str]
|
|
mov [edi+STREAM.base], eax
|
|
mov [edi+STREAM.seg_0], eax
|
|
mov [edi+STREAM.curr_seg], eax
|
|
mov [edi+STREAM.notify_off1], eax
|
|
add eax, 0x7FFF
|
|
mov [edi+STREAM.lim_0], eax
|
|
inc eax
|
|
mov [edi+STREAM.seg_1], eax
|
|
mov [edi+STREAM.notify_off2], eax
|
|
add eax, 0x7FFF
|
|
mov [edi+STREAM.limit], eax
|
|
mov [edi+STREAM.lim_1], eax
|
|
inc eax
|
|
|
|
mov [edi+STREAM.work_buff], eax
|
|
mov [edi+STREAM.work_read], eax
|
|
mov [edi+STREAM.work_write], eax
|
|
mov [edi+STREAM.work_count], 0
|
|
add eax, 0x10000
|
|
mov [edi+STREAM.work_top], eax
|
|
add eax, 1024*32
|
|
mov [edi+STREAM.r_buff], eax
|
|
|
|
mov ebx, [CURRENT_TASK]
|
|
shl ebx, 5
|
|
mov eax, [0x3000+ebx+4]
|
|
|
|
mov [edi+STREAM.notify_task], eax
|
|
|
|
mov eax, [format]
|
|
mov [edi+STREAM.format], eax
|
|
mov [edi+STREAM.flags], SND_STOP
|
|
|
|
xor ebx, ebx
|
|
cmp eax, 19
|
|
jb @f
|
|
mov ebx, 0x80808080
|
|
@@:
|
|
mov [edi+STREAM.r_silence], ebx
|
|
|
|
shl eax, 4
|
|
mov ebx, [resampler_params+eax]
|
|
mov ecx, [resampler_params+eax+4]
|
|
mov edx, [resampler_params+eax+8]
|
|
|
|
mov [edi+STREAM.r_size],ebx
|
|
mov [edi+STREAM.r_end], ecx
|
|
mov [edi+STREAM.r_dt], edx
|
|
|
|
mov ebx, [resampler_params+eax+12]
|
|
mov [edi+STREAM.resample], ebx
|
|
|
|
mov edi, [edi+STREAM.base]
|
|
mov ecx, 180*1024/4
|
|
xor eax, eax
|
|
rep stosd
|
|
|
|
mov eax, [str]
|
|
ret
|
|
.fail:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
pid_to_slot:
|
|
|
|
push ebx
|
|
push ecx
|
|
mov ebx,[TASK_COUNT]
|
|
shl ebx,5
|
|
mov ecx,2*32
|
|
.loop:
|
|
cmp byte [CURRENT_TASK+ecx+0xa],9
|
|
jz .endloop ;skip empty slots
|
|
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID
|
|
jz .pid_found
|
|
.endloop:
|
|
add ecx,32
|
|
cmp ecx,ebx
|
|
jle .loop
|
|
pop ecx
|
|
pop ebx
|
|
xor eax,eax
|
|
ret
|
|
|
|
.pid_found:
|
|
shr ecx,5
|
|
mov eax,ecx
|
|
pop ecx
|
|
pop ebx
|
|
ret
|
|
|
|
align 4
|
|
proc DestroyBuffer stdcall, str:dword
|
|
|
|
mov esi, [str]
|
|
|
|
cmp [esi+STREAM.magic], 'WAVE'
|
|
jne .fail
|
|
|
|
cmp [esi+STREAM.size], STREAM_SIZE
|
|
jne .fail
|
|
|
|
stdcall KernelFree, [esi+STREAM.base]
|
|
|
|
mov eax, [str]
|
|
call free_stream
|
|
|
|
mov edi, [str]
|
|
mov ecx, STREAM_SIZE/4
|
|
xor eax, eax
|
|
cld
|
|
rep stosd
|
|
|
|
mov eax, [str]
|
|
mov esi, stream_list
|
|
mov ecx, 16
|
|
@@:
|
|
cmp [esi], eax
|
|
je .remove
|
|
add esi, 4
|
|
dec ecx
|
|
jnz @B
|
|
xor eax, eax
|
|
inc eax
|
|
ret
|
|
.remove:
|
|
mov edi, esi
|
|
add esi, 4
|
|
cld
|
|
rep movsd
|
|
dec [stream_count]
|
|
xor eax, eax
|
|
inc eax
|
|
ret
|
|
.fail:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc play_buffer stdcall, str:dword
|
|
|
|
mov ebx, [str]
|
|
|
|
cmp [ebx+STREAM.magic], 'WAVE'
|
|
jne .fail
|
|
|
|
cmp [ebx+STREAM.size], STREAM_SIZE
|
|
jne .fail
|
|
|
|
mov [ebx+STREAM.flags], SND_PLAY
|
|
|
|
mov eax,[ebx+STREAM.work_buff]
|
|
mov [ebx+STREAM.work_read], eax
|
|
mov [ebx+STREAM.work_write], eax
|
|
mov [ebx+STREAM.work_count], 0
|
|
|
|
mov eax, [ebx+STREAM.seg_0]
|
|
mov [ebx+STREAM.curr_seg], eax
|
|
|
|
mov esi, [ebx+STREAM.curr_seg]
|
|
mov edi, [ebx+STREAM.work_write]
|
|
mov edx, [ebx+STREAM.r_buff]
|
|
|
|
mov ecx, 32
|
|
mov eax, [ebx+STREAM.r_silence]
|
|
@@:
|
|
mov [edx], eax
|
|
add edx, 4
|
|
dec ecx
|
|
jnz @B
|
|
|
|
mov edx, [ebx+STREAM.r_buff]
|
|
|
|
stdcall [ebx+STREAM.resample], edi, esi, edx,\
|
|
[ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end]
|
|
|
|
mov ebx, [str]
|
|
|
|
add [ebx+STREAM.work_count], eax;
|
|
add [ebx+STREAM.work_write], eax;
|
|
|
|
mov eax, [ebx+STREAM.r_size]
|
|
add [ebx+STREAM.curr_seg], eax
|
|
|
|
; if DEBUG
|
|
; mov esi, msgPlay
|
|
; call [SysMsgBoardStr]
|
|
; end if
|
|
|
|
stdcall dev_play, [hSound]
|
|
xor eax, eax
|
|
inc eax
|
|
ret
|
|
.fail:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc stop_buffer stdcall, str:dword
|
|
|
|
mov edi, [str]
|
|
|
|
cmp [edi+STREAM.magic], 'WAVE'
|
|
jne .fail
|
|
|
|
cmp [edi+STREAM.size], STREAM_SIZE
|
|
jne .fail
|
|
|
|
mov [edi+STREAM.flags], SND_STOP
|
|
|
|
; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
|
|
|
|
xor eax, eax
|
|
inc eax
|
|
ret
|
|
.fail:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
|
|
|
|
mov edx, [str]
|
|
test edx, edx
|
|
jz .fail
|
|
|
|
cmp [edx+STREAM.magic], 'WAVE'
|
|
jne .fail
|
|
|
|
cmp [edx+STREAM.size], STREAM_SIZE
|
|
jne .fail
|
|
|
|
mov esi,[src]
|
|
test esi, esi
|
|
jz .fail
|
|
|
|
cmp esi, new_app_base
|
|
jb .fail
|
|
|
|
mov ecx, [size]
|
|
test ecx, ecx
|
|
jz .fail
|
|
|
|
mov eax, [edx+STREAM.base]
|
|
add eax, [offs]
|
|
|
|
cmp eax, [edx+STREAM.base]
|
|
jb .fail
|
|
|
|
mov edi, eax
|
|
add eax, ecx
|
|
sub eax, 1
|
|
|
|
cmp eax, [edx+STREAM.limit]
|
|
ja .fail
|
|
|
|
shr ecx, 2
|
|
cld
|
|
rep movsd
|
|
|
|
xor eax, eax
|
|
inc eax
|
|
ret
|
|
.fail:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc alloc_stream
|
|
|
|
mov esi, stream_map
|
|
|
|
pushf
|
|
cli
|
|
|
|
bsf eax, [esi]
|
|
jnz .find
|
|
popf
|
|
xor eax, eax
|
|
ret
|
|
.find:
|
|
btr [esi], eax
|
|
popf
|
|
mov ebx, STREAM_SIZE
|
|
mul ebx
|
|
add eax, stream
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc free_stream
|
|
sub eax, stream
|
|
mov ebx, STREAM_SIZE
|
|
xor edx, edx
|
|
div ebx
|
|
|
|
and edx, edx
|
|
jnz .err
|
|
|
|
bts [stream_map], eax
|
|
ret
|
|
.err:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
if 0
|
|
align 4
|
|
proc check_stream
|
|
|
|
xor edx, edx
|
|
mov ecx, [play_count]
|
|
.l1:
|
|
mov esi, [play_list+edx]
|
|
|
|
mov eax, [esi+STR.curr_seg]
|
|
cmp eax, [esi+STR.lim_0]
|
|
jb .next
|
|
|
|
mov eax, [esi+STREAM.seg_0]
|
|
mov ecx, [esi+STREAM.lim_0]
|
|
xchg eax, [ebx+STREAM.seg_1]
|
|
xchg ecx, [ebx+STREAM.lim_1]
|
|
mov [esi+STREAM.seg_0], eax
|
|
mov [esi+STREAM.lim_0], ecx
|
|
mov [esi+STR.curr_seg], eax
|
|
.next:
|
|
add edx, 4
|
|
loop .l1
|
|
ret
|
|
endp
|
|
end if
|
|
|
|
align 4
|
|
proc prepare_playlist
|
|
|
|
.restart:
|
|
xor ebx, ebx
|
|
xor edx, edx
|
|
mov [play_count], 0
|
|
mov ecx, [stream_count]
|
|
jcxz .exit
|
|
.l1:
|
|
mov esi, [stream_list+ebx]
|
|
test esi, esi
|
|
jz .next
|
|
|
|
cmp [esi+STREAM.magic], 'WAVE'
|
|
jne .next
|
|
|
|
cmp [esi+STREAM.size], STREAM_SIZE
|
|
jne .next
|
|
|
|
mov eax,[esi+STREAM.notify_task]
|
|
cmp eax, -1
|
|
je .fail
|
|
|
|
call pid_to_slot
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
cmp [esi+STREAM.flags], SND_PLAY;
|
|
jne .next
|
|
cmp [esi+STREAM.work_count], 16384
|
|
jb .next
|
|
|
|
mov [play_list+edx], esi
|
|
inc [play_count]
|
|
add edx, 4
|
|
.next:
|
|
add ebx, 4
|
|
loop .l1
|
|
.exit:
|
|
ret
|
|
.fail:
|
|
stdcall DestroyBuffer, esi
|
|
jmp .restart
|
|
endp
|
|
|
|
align 4
|
|
proc prepare_updatelist
|
|
|
|
xor ebx, ebx
|
|
xor edx, edx
|
|
mov [play_count], 0
|
|
mov ecx, [stream_count]
|
|
jcxz .exit
|
|
.l1:
|
|
mov eax, [stream_list+ebx]
|
|
test eax, eax
|
|
jz .next
|
|
cmp [eax+STREAM.flags], SND_PLAY
|
|
jne .next
|
|
|
|
mov [play_list+edx], eax
|
|
inc [play_count]
|
|
add edx, 4
|
|
.next:
|
|
add ebx, 4
|
|
loop .l1
|
|
.exit:
|
|
ret
|
|
endp
|
|
|
|
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]
|
|
stdcall 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]
|
|
stdcall ServiceHandler, eax
|
|
ret
|
|
endp
|
|
|
|
include 'mixer.asm'
|
|
|
|
align 16
|
|
resampler_params:
|
|
;r_size r_end r_dt resampler_func
|
|
dd 0,0,0,0 ; 0 PCM_ALL
|
|
dd 16384, 0, 0, copy_stream ; 1 PCM_2_16_48
|
|
dd 16384, 0, 0, m16_stereo ; 2 PCM_1_16_48
|
|
|
|
dd 16384, 0x08000000, 30109, resample_2 ; 3 PCM_2_16_44
|
|
dd 8192, 0x08000000, 30109, resample_1 ; 4 PCM_1_16_44
|
|
|
|
dd 16384, 0x08000000, 21846, resample_2 ; 5 PCM_2_16_32
|
|
dd 8192, 0x08000000, 21846, resample_1 ; 6 PCM_1_16_32
|
|
|
|
dd 16384, 0x08000000, 16384, resample_2 ; 7 PCM_2_16_24
|
|
dd 8192, 0x08000000, 16384, resample_1 ; 8 PCM_1_16_24
|
|
|
|
dd 8192, 0x04000000, 15052, resample_2 ; 9 PCM_2_16_22
|
|
dd 4096, 0x04000000, 15052, resample_1 ;10 PCM_1_16_22
|
|
|
|
dd 8192, 0x04000000, 10923, resample_2 ;11 PCM_2_16_16
|
|
dd 4096, 0x04000000, 10923, resample_1 ;12 PCM_1_16_16
|
|
|
|
dd 8192, 0x04000000, 8192, resample_2 ;13 PCM_2_16_12
|
|
dd 4096, 0x04000000, 8192, resample_1 ;14 PCM_1_16_12
|
|
|
|
dd 4096, 0x02000000, 7527, resample_2 ;15 PCM_2_16_11
|
|
dd 2048, 0x02000000, 7527, resample_1 ;16 PCM_1_16_11
|
|
|
|
dd 4096, 0x02000000, 5462, resample_2 ;17 PCM_2_16_8
|
|
dd 2048, 0x02000000, 5462, resample_1 ;18 PCM_1_16_8
|
|
|
|
dd 16384, 0, 0, s8_stereo ;19 PCM_2_8_48
|
|
dd 8192, 0, 0, m8_stereo ;20 PCM_1_8_48
|
|
|
|
dd 8192, 0x08000000, 30109, resample_28 ;21 PCM_2_8_44
|
|
dd 4096, 0x08000000, 30109, resample_18 ;22 PCM_1_8_44
|
|
|
|
dd 8192, 0x08000000, 21846, resample_28 ;23 PCM_2_8_32
|
|
dd 4096, 0x08000000, 21846, resample_18 ;24 PCM_1_8_32
|
|
|
|
dd 8192, 0x08000000, 16384, resample_28 ;25 PCM_2_8_24
|
|
dd 4096, 0x08000000, 16384, resample_18 ;26 PCM_1_8_24
|
|
|
|
dd 4096, 0x04000000, 15052, resample_28 ;27 PCM_2_8_22
|
|
dd 2048, 0x04000000, 15052, resample_18 ;28 PCM_1_8_22
|
|
|
|
dd 4096, 0x04000000, 10923, resample_28 ;29 PCM_2_8_16
|
|
dd 2048, 0x04000000, 10923, resample_18 ;30 PCM_1_8_16
|
|
|
|
dd 4096, 0x04000000, 8192, resample_28 ;31 PCM_2_8_12
|
|
dd 2048, 0x04000000, 8192, resample_18 ;32 PCM_1_8_12
|
|
|
|
dd 2048, 0x02000000, 7527, resample_28 ;33 PCM_2_8_11
|
|
dd 1024, 0x02000000, 7527, resample_18 ;34 PCM_1_8_11
|
|
|
|
dd 2048, 0x02000000, 5462, resample_28 ;35 PCM_2_8_8
|
|
dd 1024, 0x02000000, 5462, resample_18 ;36 PCM_1_8_8
|
|
|
|
m7 dw 0x8000,0x8000,0x8000,0x8000
|
|
mm80 dq 0x8080808080808080
|
|
mm_mask dq 0xFF00FF00FF00FF00
|
|
|
|
stream_map dd 0xFFFF ; 16
|
|
version dd 0x00020002
|
|
|
|
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
|
|
end if
|
|
|
|
section '.data' data readable writable align 16
|
|
|
|
stream rb STREAM_SIZE*16
|
|
|
|
play_list rd 16
|
|
mix_input rd 16
|
|
|
|
stream_list rd 17
|
|
play_count rd 1
|
|
stream_count rd 1
|
|
hSound rd 1
|
|
mix_buff rd 1
|
|
mix_buff_map rd 1
|
|
|