Subversion Repositories Kolibri OS

Rev

Rev 1917 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. ; Serge 2006-2008
  9. ; email: infinity_sound@mail.ru
  10.  
  11. format MS COFF
  12.  
  13. DEBUG             equ 1
  14.  
  15.  
  16. include 'proc32.inc'
  17. include 'main.inc'
  18. include 'imports.inc'
  19.  
  20.  
  21. CURRENT_API     equ   0x0101      ;1.01
  22. COMPATIBLE_API  equ   0x0100      ;1.00
  23.  
  24. API_VERSION     equ   (COMPATIBLE_API shl 16) or CURRENT_API
  25. SOUND_VERSION   equ   CURRENT_API
  26.  
  27.  
  28. FORCE_MMX         equ 0  ;set to 1 to force use mmx or
  29. FORCE_MMX_128     equ 0  ;integer sse2 extensions
  30.                          ;and reduce driver size
  31.  
  32. ;USE_SSE          equ 0
  33.  
  34. USE_SSE2_MIXER    equ 0  ;floating point mixer. Disabled by default
  35.  
  36. OS_BASE           equ 0x80000000
  37.  
  38. CAPS_SSE2         equ 26
  39. PG_SW             equ 0x003
  40.  
  41. public START
  42. public service_proc
  43. public version
  44.  
  45. RT_INP_EMPTY      equ 0xFF000001
  46. RT_OUT_EMPTY      equ 0xFF000002
  47. RT_INP_FULL       equ 0xFF000003
  48. RT_OUT_FULL       equ 0xFF000004
  49.  
  50. EVENT_WATCHED     equ 0x10000000
  51. EVENT_SIGNALED    equ 0x20000000
  52. MANUAL_RESET      equ 0x40000000
  53. MANUAL_DESTROY    equ 0x80000000
  54.  
  55. DEV_PLAY          equ 1
  56. DEV_STOP          equ 2
  57. DEV_CALLBACK      equ 3
  58. DEV_GET_POS       equ 9
  59.  
  60. struc IOCTL
  61. {  .handle        dd ?
  62.    .io_code       dd ?
  63.    .input         dd ?
  64.    .inp_size      dd ?
  65.    .output        dd ?
  66.    .out_size      dd ?
  67. }
  68.  
  69. virtual at 0
  70.   IOCTL IOCTL
  71. end virtual
  72.  
  73. section '.flat' code readable align 16
  74.  
  75. proc START stdcall, state:dword
  76.  
  77.         cmp     [state], 1
  78.         jne     .exit
  79.  
  80.         stdcall GetService, szSound
  81.         test    eax, eax
  82.         jz      .fail
  83.         mov     [hSound], eax
  84.  
  85.         stdcall KernelAlloc, 16*512
  86.         test    eax, eax
  87.         jz      .out_of_mem
  88.         mov     [mix_buff], eax
  89.  
  90.         mov     eax, str.fd-FD_OFFSET
  91.         mov     [str.fd], eax
  92.         mov     [str.bk], eax
  93.  
  94. if FORCE_MMX
  95.  if FORCE_MMX_128
  96.   display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
  97.   stop
  98.  end if
  99.         mov     [mix_2_core], mmx_mix_2
  100.         mov     [mix_3_core], mmx_mix_3
  101.         mov     [mix_4_core], mmx_mix_4
  102. end if
  103.  
  104. if FORCE_MMX_128
  105.  if FORCE_MMX
  106.   display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
  107.   stop
  108.  end if
  109.         mov     [mix_2_core], mmx128_mix_2
  110.         mov     [mix_3_core], mmx128_mix_3
  111.         mov     [mix_4_core], mmx128_mix_4
  112. end if
  113.  
  114. if 0
  115.  
  116. if ~(FORCE_MMX or FORCE_MMX_128)  ;autodetect
  117.         mov     eax, 1
  118.         cpuid
  119.         bt      edx, CAPS_SSE2
  120.         jc      .mmx128
  121.                                            ;old 64-bit mmx
  122.         mov     [mix_2_core], mmx_mix_2
  123.         mov     [mix_3_core], mmx_mix_3
  124.         mov     [mix_4_core], mmx_mix_4
  125.         jmp     @F
  126. .mmx128:                                   ;128-bit integer sse2 extensions
  127.         mov     [mix_2_core], mmx128_mix_2
  128.         mov     [mix_3_core], mmx128_mix_3
  129.         mov     [mix_4_core], mmx128_mix_4
  130. @@:
  131. end if
  132.  
  133. end if
  134.         stdcall set_handler, [hSound], new_mix
  135.         mov     [eng_state], SND_STOP
  136.         stdcall RegService, szInfinity, service_proc
  137.         ret
  138. .fail:
  139.      if DEBUG
  140.         mov     esi, msgFail
  141.         call    SysMsgBoardStr
  142.      end if
  143. .exit:
  144.         xor     eax, eax
  145.         ret
  146.  
  147. .out_of_mem:
  148.      if DEBUG
  149.         mov     esi, msgMem
  150.         call    SysMsgBoardStr
  151.      end if
  152.         xor     eax, eax
  153.         ret
  154. endp
  155.  
  156. handle     equ  IOCTL.handle
  157. io_code    equ  IOCTL.io_code
  158. input      equ  IOCTL.input
  159. inp_size   equ  IOCTL.inp_size
  160. output     equ  IOCTL.output
  161. out_size   equ  IOCTL.out_size
  162.  
  163.  
  164.  
  165. align 4
  166.  
  167. srv_calls  dd service_proc.srv_getversion       ; 0
  168.            dd service_proc.snd_create_buff      ; 1
  169.            dd service_proc.snd_destroy_buff     ; 2
  170.            dd service_proc.snd_setformat        ; 3
  171.            dd service_proc.snd_getformat        ; 4
  172.            dd service_proc.snd_reset            ; 5
  173.            dd service_proc.snd_setpos           ; 6
  174.            dd service_proc.snd_getpos           ; 7
  175.            dd service_proc.snd_setbuff          ; 8
  176.            dd service_proc.snd_out              ; 9
  177.            dd service_proc.snd_play             ; 10
  178.            dd service_proc.snd_stop             ; 11
  179.            dd service_proc.snd_setvolume        ; 12
  180.            dd service_proc.snd_getvolume        ; 13
  181.            dd service_proc.snd_setpan           ; 14
  182.            dd service_proc.snd_getpan           ; 15
  183.            dd service_proc.snd_getbuffsize      ; 16
  184.            dd service_proc.snd_getfreespace     ; 17
  185.            dd service_proc.snd_settimebase      ; 18
  186.            dd service_proc.snd_gettimestamp     ; 19
  187. srv_calls_end:
  188.  
  189. proc service_proc stdcall, ioctl:dword
  190.  
  191.         mov     edi, [ioctl]
  192.         mov     eax, [edi+io_code]
  193.  
  194.         cmp     eax, (srv_calls_end-srv_calls)/4
  195.         ja      .fail
  196.  
  197.         cmp     eax, SND_DESTROY_BUFF
  198.         jb      @F
  199.  
  200. ;           cmp [edi+inp_size], 4
  201. ;           jb .fali
  202.  
  203.         mov     ebx, [edi+input]
  204.         mov     edx, [ebx]
  205.  
  206.         cmp     [edx+STREAM.magic], 'WAVE'
  207.         jne     .fail
  208.  
  209.         cmp     [edx+STREAM.size], STREAM.sizeof
  210.         jne     .fail
  211.  
  212. @@:
  213.         jmp     [srv_calls+eax*4]
  214.  
  215.  
  216. .fail:
  217.         mov     eax, -1
  218.         ret
  219.  
  220. align 4
  221. .srv_getversion:
  222.         mov     eax, [edi+output]
  223.         cmp     [edi+out_size], 4
  224.         jne     .fail
  225.         mov     eax, [eax]
  226.         mov     [eax], dword API_VERSION
  227.         xor     eax, eax
  228.         ret
  229.  
  230. align 4
  231. .snd_create_buff:
  232.         mov     ebx, [edi+input]
  233.         stdcall CreateBuffer, [ebx], [ebx+4]
  234.         mov     edi, [ioctl]
  235.         mov     ecx, [edi+output]
  236.         mov     ecx, [ecx]
  237.         mov     [ecx], ebx
  238.         ret
  239.  
  240. align 4
  241. .snd_destroy_buff:
  242.         mov     eax, edx
  243.         call    DestroyBuffer
  244.         ret
  245.  
  246. align 4
  247. .snd_setformat:
  248.         stdcall SetFormat, edx, [ebx+4]
  249.         ret
  250.  
  251. align 4
  252. .snd_getformat:
  253.         movzx   eax, word [edx+STREAM.format]
  254.         mov     ecx, [edi+output]
  255.         mov     ecx, [ecx]
  256.         mov     [ecx], eax
  257.         xor     eax, eax
  258.         ret
  259.  
  260. align 4
  261. .snd_reset:
  262.         stdcall ResetBuffer, edx, [ebx+4]
  263.         ret
  264.  
  265. align 4
  266. .snd_setpos:
  267.         stdcall SetBufferPos, edx, [ebx+4]
  268.         ret
  269.  
  270. align 4
  271. .snd_getpos:
  272.         stdcall GetBufferPos, edx
  273.         mov     edi, [ioctl]
  274.         mov     ecx, [edi+output]
  275.         mov     ecx, [ecx]
  276.         mov     [ecx], ebx
  277.         ret
  278.  
  279. align 4
  280. .snd_setbuff:
  281.         mov     eax, [ebx+4]
  282.         stdcall set_buffer, edx, eax, [ebx+8], [ebx+12]
  283.         ret
  284.  
  285. align 4
  286. .snd_out:
  287.         mov     eax, [ebx+4]
  288.         stdcall wave_out, edx, eax, [ebx+8]
  289.         ret
  290.  
  291. align 4
  292. .snd_play:
  293.         stdcall play_buffer, edx, [ebx+4]
  294.         ret
  295.  
  296. align 4
  297. .snd_stop:
  298.         stdcall stop_buffer, edx
  299.         ret
  300.  
  301. align 4
  302. .snd_setvolume:
  303.         stdcall SetBufferVol, edx, [ebx+4], [ebx+8]
  304.         ret
  305.  
  306. align 4
  307. .snd_getvolume:
  308.         mov     eax, [edi+output]
  309.         mov     ecx, [eax]
  310.         mov     eax, [eax+4]
  311.         stdcall GetBufferVol, edx, ecx, eax
  312.         ret
  313. align 4
  314. .snd_setpan:
  315.         stdcall SetBufferPan, edx, [ebx+4]
  316.         ret
  317.  
  318. align 4
  319. .snd_getpan:
  320.         mov     eax, [edx+STREAM.pan]
  321.         mov     ebx, [edi+output]
  322.         mov     ebx, [ebx]
  323.         mov     [ebx], eax
  324.         xor     eax, eax
  325.         ret
  326.  
  327. align 4
  328. .snd_getbuffsize:
  329.         mov     eax, [edx+STREAM.in_size]
  330.         mov     ecx, [edi+output]
  331.         mov     ecx, [ecx]
  332.         mov     [ecx], eax
  333.         xor     eax, eax
  334.         ret
  335.  
  336. align 4
  337. .snd_getfreespace:
  338.         test    [edx+STREAM.format], PCM_OUT
  339.         jz      .fail
  340.  
  341.         mov     ebx, [edx+STREAM.in_free]
  342.         mov     ecx, [edi+output]
  343.         mov     [ecx], ebx
  344.         xor     eax, eax
  345.         ret
  346. align 4
  347. .snd_settimebase:
  348.         cmp     [edi+inp_size], 12
  349.         jne     .fail
  350.  
  351.         mov     eax, [ebx]
  352.         mov     ebx, [ebx+4]
  353.         mov     dword [edx+STREAM.time_base], eax
  354.         mov     dword [edx+STREAM.time_base+4], ebx
  355.         xor     eax, eax
  356.         ret
  357.  
  358. .snd_gettimestamp:
  359.         cmp     [edi+out_size], 8
  360.         jne     .fail
  361.  
  362.         pushfd
  363.         cli
  364.  
  365.         xor     ebx, ebx
  366.         push    48
  367.         push    ebx            ; local storage
  368.  
  369.         cmp     [edx+STREAM.flags], SND_STOP
  370.         je      @F
  371.  
  372.         mov     eax, esp
  373.  
  374.         push    edx
  375.         push    edi
  376.  
  377.         push    4              ;.out_size
  378.         push    eax            ;.output
  379.         push    ebx            ;.inp_size
  380.         push    ebx            ;.input
  381.         push    DEV_GET_POS    ;.code
  382.         push    dword [hSound] ;.handle
  383.         mov     eax, esp
  384.  
  385.         stdcall ServiceHandler, eax
  386.         add     esp, 6*4
  387.  
  388.         pop     edi
  389.         pop     edx
  390.  
  391.         test    eax, eax
  392.         jz      @F
  393.  
  394.         mov     dword [esp], 0  ; clear offset
  395. @@:
  396.         mov     edi, [edi+output]
  397.  
  398.         emms
  399.         fild    qword [edx+STREAM.time_stamp]
  400.         fiadd   dword [esp]     ; primary buffer offset
  401.         fidiv   dword [esp+4]   ; total_samples / frequency
  402.         fadd    qword [edx+STREAM.time_base]
  403.         fstp    qword [edi]
  404.         add     esp, 8
  405.  
  406.         popfd
  407.  
  408.         xor     eax, eax
  409.         ret
  410. endp
  411.  
  412.  
  413. restore   handle
  414. restore   io_code
  415. restore   input
  416. restore   inp_size
  417. restore   output
  418. restore   out_size
  419.  
  420. align 4
  421. proc CreateBuffer stdcall, format:dword, size:dword
  422.            locals
  423.         str     dd ?
  424.              ring_size   dd ?
  425.              ring_pages  dd ?
  426.            endl
  427.  
  428.         mov     eax, [format]
  429.         cmp     ax, PCM_1_8_8
  430.         ja      .fail
  431.  
  432.         test    eax, PCM_OUT
  433.         jnz     .test_out
  434.         test    eax, PCM_RING
  435.         jnz     .test_ring
  436. ;staic
  437.         test    eax, PCM_STATIC
  438.         jz      .test_out                 ;use PCM_OUT as default format
  439.         jmp     .test_ok
  440. .test_out:
  441.         test    eax, PCM_RING+PCM_STATIC
  442.         jnz     .fail
  443.         or      [format], PCM_OUT         ;force set
  444.         jmp     .test_ok
  445. .test_ring:
  446.         test    eax, PCM_OUT+PCM_STATIC
  447.         jnz     .fail
  448. .test_ok:
  449.  
  450.         call    GetPid
  451.         mov     ebx, eax
  452.         mov     eax, STREAM.sizeof
  453.  
  454.         call    CreateObject
  455.         test    eax, eax
  456.         jz      .fail
  457.         mov     [str], eax
  458.  
  459.         mov     ebx, [format]
  460.         mov     [eax+STREAM.format], ebx
  461.  
  462.         xor     ecx, ecx
  463.         movzx   ebx, bx
  464.         cmp     ebx, 19
  465.         jb      @f
  466.         mov     ecx, 0x80808080
  467. @@:
  468.         mov     [eax+STREAM.r_silence], ecx
  469.  
  470.         shl     ebx, 2
  471.         lea     ebx, [ebx+ebx*2]    ;ebx*=12
  472.  
  473.         mov     ecx, [resampler_params+ebx]
  474.         mov     edx, [resampler_params+ebx+4]
  475.         mov     esi, [resampler_params+ebx+8]
  476.  
  477.         mov     [eax+STREAM.r_size], ecx
  478.         mov     [eax+STREAM.r_dt], edx
  479.         mov     [eax+STREAM.resample], esi
  480.         xor     ecx, ecx
  481.         mov     [eax+STREAM.l_vol], ecx
  482.         mov     [eax+STREAM.r_vol], ecx
  483.         mov     dword [eax+STREAM.l_amp], 0x7FFF7FFF
  484.         mov     [eax+STREAM.pan], ecx
  485.  
  486.         test    [format], PCM_STATIC
  487.         jnz     .static
  488.  
  489. ; ring and waveout
  490.  
  491.         mov     ebx, 0x10000
  492.         test    [format], PCM_RING
  493.         jz      .waveout
  494.  
  495.         mov     ebx, [eax+STREAM.r_size]
  496.         add     ebx, 4095
  497.         and     ebx, -4096
  498.         add     ebx, ebx
  499. .waveout:
  500.         mov     [ring_size], ebx
  501.         mov     eax, ebx
  502.         shr     ebx, 12
  503.         mov     [ring_pages], ebx
  504.  
  505.         stdcall CreateRingBuffer, eax, PG_SW
  506.  
  507.         mov     edi, [str]
  508.         mov     ecx, [ring_size]
  509.         mov     [edi+STREAM.in_base], eax
  510.         mov     [edi+STREAM.in_size], ecx
  511.         add     eax, 128
  512.         mov     [edi+STREAM.in_wp], eax
  513.         mov     [edi+STREAM.in_rp], eax
  514.         mov     [edi+STREAM.in_count], 0
  515.  
  516.         mov     [edi+STREAM.in_free], ecx
  517.         add     eax, ecx
  518.         mov     [edi+STREAM.in_top], eax
  519.  
  520.         jmp     .out_buff
  521. .static:
  522.         mov     ecx, [size]
  523.         add     ecx, 128         ;resampler required
  524.         mov     [eax+STREAM.in_size], ecx
  525.         stdcall KernelAlloc, ecx
  526.  
  527.         mov     edi, [str]
  528.         mov     [edi+STREAM.in_base], eax
  529.         add     eax, 128
  530.         mov     [edi+STREAM.in_wp], eax
  531.         mov     [edi+STREAM.in_rp], eax
  532.         mov     ebx, [size]
  533.         mov     [edi+STREAM.in_count], ebx
  534.         mov     [edi+STREAM.in_free], ebx
  535.         add     eax, ebx
  536.         mov     [edi+STREAM.in_top], eax
  537.  
  538. .out_buff:
  539.         stdcall AllocKernelSpace, dword 128*1024
  540.  
  541.         mov     edi, [str]
  542.         xor     ebx, ebx
  543.  
  544.         mov     [edi+STREAM.out_base], eax
  545.         mov     [edi+STREAM.out_wp], eax
  546.         mov     [edi+STREAM.out_rp], eax
  547.         mov     [edi+STREAM.out_count], ebx
  548.         add     eax, 64*1024
  549.         mov     [edi+STREAM.out_top], eax
  550.  
  551.         mov     dword [edi+STREAM.time_base], ebx
  552.         mov     dword [edi+STREAM.time_base+4], ebx
  553.  
  554.         mov     dword [edi+STREAM.time_stamp], ebx
  555.         mov     dword [edi+STREAM.time_stamp+4], ebx
  556.         mov     dword [edi+STREAM.last_ts], ebx
  557.  
  558.         stdcall AllocPages, dword 64/4
  559.         mov     edi, [str]
  560.         mov     ebx, [edi+STREAM.out_base]
  561.         mov     ecx, 16
  562.         or      eax, PG_SW
  563.         push    eax
  564.         push    ebx
  565.         call    CommitPages ;eax, ebx, ecx
  566.         mov     ecx, 16
  567.         pop     ebx
  568.         pop     eax
  569.         add     ebx, 64*1024
  570.         call    CommitPages    ;double mapped
  571.  
  572.         mov     edi, [str]
  573.         mov     ecx, [edi+STREAM.in_top]
  574.         mov     edi, [edi+STREAM.in_base]
  575.         sub     ecx, edi
  576.         xor     eax, eax
  577.         shr     ecx, 2
  578.         cld
  579.         rep stosd
  580.  
  581.         mov     edi, [str]
  582.         mov     edi, [edi+STREAM.out_base]
  583.         mov     ecx, (64*1024)/4
  584.         rep stosd
  585.  
  586.         xor     esi, esi
  587.         mov     ecx, MANUAL_DESTROY
  588.         call    CreateEvent
  589.  
  590.         mov     ebx, [str]
  591.         mov     [ebx+STREAM.notify_event], eax
  592.         mov     [ebx+STREAM.notify_id], edx
  593.  
  594.         mov     [ebx+STREAM.magic], 'WAVE'
  595.         mov     [ebx+STREAM.destroy], DestroyBuffer.destroy
  596.         mov     [ebx+STREAM.size], STREAM.sizeof
  597.         mov     [ebx+STREAM.flags], SND_STOP
  598.  
  599.         pushf
  600.         cli
  601.         mov     eax, str.fd-FD_OFFSET
  602.         mov     edx, [eax+STREAM.str_fd]
  603.         mov     [ebx+STREAM.str_fd], edx
  604.         mov     [ebx+STREAM.str_bk], eax
  605.         mov     [eax+STREAM.str_fd], ebx
  606.         mov     [edx+STREAM.str_bk], ebx
  607.         popf
  608.  
  609.         xor     eax, eax
  610.         ret
  611. .fail:
  612.         xor     ebx, ebx
  613.         or      eax, -1
  614.         ret
  615. endp
  616.  
  617. ;param
  618. ; eax= buffer handle
  619.  
  620. align 4
  621. DestroyBuffer:
  622.            .handle  equ esp       ;local
  623.  
  624.         mov     [eax+STREAM.flags], SND_STOP
  625. .destroy:
  626.         push    eax
  627.  
  628.         pushfd
  629.         cli
  630.         mov     ebx, [eax+STREAM.str_fd]
  631.         mov     ecx, [eax+STREAM.str_bk]
  632.         mov     [ebx+STREAM.str_bk], ecx
  633.         mov     [ecx+STREAM.str_fd], ebx
  634.         popf
  635.  
  636.         stdcall KernelFree, [eax+STREAM.in_base]
  637.         mov     eax, [.handle]
  638.         stdcall KernelFree, [eax+STREAM.out_base]
  639.  
  640.         pop     eax              ;restore stack
  641.         call    DestroyObject    ;eax= stream
  642.         xor     eax, eax
  643.         ret
  644. .fail:
  645.         or      eax, -1
  646.         ret
  647. restore .handle
  648.  
  649. align 4
  650. proc SetFormat stdcall, str:dword, format:dword
  651.  
  652.         cmp     word [format], PCM_1_8_8
  653.         ja      .fail
  654.  
  655.         mov     edx, [str]
  656.         mov     [edx+STREAM.flags], SND_STOP
  657.  
  658.         test    [edx+STREAM.format], PCM_RING
  659.         jnz     .fail
  660.  
  661. ;           mov eax,[edx+STREAM.out_base]
  662. ;           mov [edx+STREAM.out_wp], eax
  663. ;           mov [edx+STREAM.out_rp], eax
  664. ;           mov [edx+STREAM.out_count], 0
  665.  
  666.         movzx   eax, word [format]
  667.         mov     word [edx+STREAM.format], ax
  668.  
  669.         xor     ebx, ebx
  670.         cmp     eax, 19
  671.         jb      @f
  672.         mov     ebx, 0x80808080
  673. @@:
  674.         mov     [edx+STREAM.r_silence], ebx
  675.  
  676.         shl     eax, 2
  677.         lea     eax, [eax+eax*2]    ;eax*=12
  678.  
  679.         mov     edi, [resampler_params+eax]
  680.         mov     ecx, [resampler_params+eax+4]
  681.         mov     ebx, [resampler_params+eax+8]
  682.  
  683.         mov     [edx+STREAM.r_size], edi
  684.         mov     [edx+STREAM.r_dt], ecx
  685.         mov     [edx+STREAM.resample], ebx
  686.  
  687.         mov     edi, [edx+STREAM.in_base]
  688.         mov     ecx, 128/4
  689.         mov     eax, [edx+STREAM.r_silence]
  690.         cld
  691.         rep stosd
  692.         xor     eax, eax
  693.         ret
  694. .fail:
  695.         or      eax, -1
  696.         ret
  697. endp
  698.  
  699. ; for static buffers only
  700. ; use waveout for streams
  701.  
  702. align 4
  703. proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
  704.  
  705.         mov     edx, [str]
  706.         test    [edx+STREAM.format], PCM_OUT
  707.         jnz     .fail
  708.  
  709.         mov     esi, [src]
  710.         mov     edi, [offs]
  711.         add     edi, [edx+STREAM.in_base]
  712.         add     edi, 128
  713.  
  714.         cmp     edi, [edx+STREAM.in_top]
  715.         jae     .fail
  716.  
  717.         mov     ecx, [size]
  718.         lea     ebx, [ecx+edi]
  719.         sub     ebx, [edx+STREAM.in_top]
  720.         jb      @F
  721.         sub     ecx, ebx
  722. @@:
  723.         shr     ecx, 2
  724.         cld
  725.         rep movsd
  726.         xor     eax, eax
  727.         ret
  728. .fail:
  729.         or      eax, -1
  730.         ret
  731. endp
  732.  
  733. ; for stream buffers only
  734.  
  735. align 4
  736. proc wave_out stdcall, str:dword,src:dword,size:dword
  737.            locals
  738.              state_saved  dd ?
  739.              fpu_state    rb 528
  740.            endl
  741.  
  742.         mov     edx, [str]
  743.         mov     eax, [edx+STREAM.format]
  744.         test    eax, PCM_OUT
  745.         jz      .fail
  746.  
  747.         cmp     ax, PCM_ALL
  748.         je      .fail
  749.  
  750.         mov     esi, [src]
  751.         test    esi, esi
  752.         jz      .fail
  753.  
  754.         cmp     esi, OS_BASE
  755.         jae     .fail
  756.  
  757.         mov     [state_saved], 0
  758.  
  759. .main_loop:
  760.         mov     edx, [str]
  761.  
  762.         mov     ebx, [size]
  763.         test    ebx, ebx
  764.         jz      .done
  765.  
  766.         cmp     [edx+STREAM.flags], SND_STOP
  767.         jne     .fill
  768.  
  769.         mov     edi, [edx+STREAM.in_base]
  770.         mov     ecx, 128/4
  771.         mov     eax, [edx+STREAM.r_silence]
  772.         cld
  773.         rep stosd
  774.  
  775.         mov     ecx, [edx+STREAM.in_size]
  776.         sub     ecx, 128
  777.         mov     [edx+STREAM.in_wp], edi
  778.         mov     [edx+STREAM.in_rp], edi
  779.         mov     [edx+STREAM.in_count], 0
  780.         mov     [edx+STREAM.in_free], ecx
  781.  
  782.         mov     eax, [edx+STREAM.out_base]
  783.         mov     [edx+STREAM.out_wp], eax
  784.         mov     [edx+STREAM.out_rp], eax
  785.         mov     [edx+STREAM.out_count], 0
  786. .fill:
  787.         cli
  788.  
  789.         mov     ecx, [edx+STREAM.in_free]
  790.         test    ecx, ecx
  791.         jz      .wait
  792.  
  793.         cmp     ecx, ebx
  794.         jbe     @F
  795.  
  796.         mov     ecx, ebx
  797. @@:
  798.         sub     [size], ecx
  799.         add     [edx+STREAM.in_count], ecx
  800.         sub     [edx+STREAM.in_free], ecx
  801.  
  802.         shr     ecx, 2
  803.         mov     edi, [edx+STREAM.in_wp]
  804.         mov     esi, [src]
  805.         cld
  806.         rep movsd
  807.  
  808.         mov     [src], esi
  809.         cmp     edi, [edx+STREAM.in_top]
  810.         jb      @F
  811.         sub     edi, [edx+STREAM.in_size]
  812. @@:
  813.         mov     [edx+STREAM.in_wp], edi
  814.  
  815.         cmp     [edx+STREAM.out_count], 32768
  816.         jae     .skip
  817.  
  818.         cmp     [state_saved], 0
  819.         jne     @F
  820.         lea     eax, [fpu_state+15]
  821.         and     eax, -16
  822.         call    FpuSave
  823.         mov     [state_saved], 1
  824. @@:
  825.         stdcall refill, edx
  826.  
  827. .skip:
  828.         sti
  829.         mov     edx, [str]
  830.         mov     [edx+STREAM.flags], SND_PLAY
  831.         cmp     [eng_state], SND_PLAY
  832.         je      .main_loop
  833.  
  834.         stdcall dev_play, [hSound]
  835.         mov     [eng_state], SND_PLAY
  836.         jmp     .main_loop
  837. .wait:
  838.         sti
  839.         mov     edx, [str]
  840.         mov     eax, [edx+STREAM.notify_event]
  841.         mov     ebx, [edx+STREAM.notify_id]
  842.         call    WaitEvent   ;eax ebx
  843.         jmp     .main_loop
  844. .done:
  845.         cmp     [state_saved], 1
  846.         jne     @F
  847.  
  848.         lea     eax, [fpu_state+15]
  849.         and     eax, -16
  850.         call    FpuRestore
  851. @@:
  852.         xor     eax, eax
  853.         ret
  854. .fail:
  855.         or      eax, -1
  856.         ret
  857. endp
  858.  
  859. ; both static and stream
  860. ; reset all but not clear buffers
  861.  
  862.  
  863. ; flags reserved
  864. ;  RESET_INPUT  equ 1   ;reserved reset and clear input buffer
  865. ;  RESET_OUTPUT equ 2   ;reserved reset and clear output buffer
  866. ;  RESET_ALL    equ 3
  867.  
  868.  
  869. align 4
  870. proc ResetBuffer stdcall, str:dword, flags:dword
  871.  
  872.         mov     edx, [str]
  873.         mov     [edx+STREAM.flags], SND_STOP
  874.  
  875.         mov     edi, [edx+STREAM.in_base]
  876.         mov     ecx, 128/4
  877.         mov     eax, [edx+STREAM.r_silence]
  878.         cld
  879.         rep stosd
  880.  
  881.         mov     [edx+STREAM.in_wp], edi
  882.         mov     [edx+STREAM.in_rp], edi
  883.  
  884.         test    [edx+STREAM.flags], PCM_STATIC
  885.         jnz     .static
  886.         mov     [edx+STREAM.in_count], 0
  887.         jmp     @F
  888. .static:
  889.         mov     eax, [edx+STREAM.in_size]
  890.         mov     [edx+STREAM.in_count], eax
  891. @@:
  892.  
  893.         mov     eax, [edx+STREAM.in_size]
  894.         sub     eax, 128
  895.         mov     [edx+STREAM.in_free], eax
  896.  
  897.         xor     eax, eax
  898.         mov     ebx, [edx+STREAM.out_base]
  899.         mov     [edx+STREAM.out_wp], ebx
  900.         mov     [edx+STREAM.out_rp], ebx
  901.         mov     [edx+STREAM.out_count], eax
  902.         ret
  903. .fail:
  904.         or      eax, -1
  905.         ret
  906. endp
  907.  
  908. ; for static buffers only
  909.  
  910. align 4
  911. proc SetBufferPos stdcall, str:dword, pos:dword
  912.  
  913.         mov     edx, [str]
  914.         test    [edx+STREAM.format], PCM_STATIC
  915.         jz      .fail
  916.  
  917.         mov     [edx+STREAM.flags], SND_STOP
  918.  
  919.         mov     eax, [pos]
  920.         add     eax, [edx+STREAM.in_base]
  921.         mov     ebx, [edx+STREAM.in_top]
  922.         add     eax, 128
  923.  
  924.         cmp     eax, ebx
  925.         jae     .fail
  926.  
  927.         mov     [edx+STREAM.in_rp], eax
  928.         sub     ebx, eax
  929.         mov     [edx+STREAM.in_count], ebx
  930.         xor     eax, eax
  931.         ret
  932. .fail:
  933.         or      eax, -1
  934.         ret
  935. endp
  936.  
  937. align 4
  938. proc GetBufferPos stdcall, str:dword
  939.  
  940.         mov     edx, [str]
  941.         test    [edx+STREAM.format], PCM_STATIC
  942.         jz      .fail
  943.  
  944.         mov     ebx, [edx+STREAM.in_rp]
  945.         sub     ebx, [edx+STREAM.in_base]
  946.         sub     ebx, 128
  947.         xor     eax, eax
  948.         ret
  949. .fail:
  950.         xor     ebx, ebx
  951.         or      eax, -1
  952.         ret
  953. endp
  954.  
  955. ; both
  956.  
  957. align 4
  958. proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword
  959.  
  960.         mov     edx, [str]
  961.         stdcall set_vol_param, [l_vol], [r_vol], [edx+STREAM.pan]
  962.         ret
  963. endp
  964.  
  965.  
  966. proc minw stdcall, arg1:dword, arg2:dword
  967.         mov     ax, word [arg1]
  968.         cmp     ax, word [arg2]
  969.         jle     @f
  970.         mov     eax, [arg2]
  971. @@:
  972.         ret
  973. endp
  974.  
  975. proc maxw stdcall, arg1:dword, arg2:dword
  976.         mov     ax, word [arg1]
  977.         cmp     ax, word [arg2]
  978.         jge     @f
  979.         mov     eax, [arg2]
  980. @@:
  981.         ret
  982. endp
  983.  
  984.  
  985. proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword
  986.            locals
  987.              _600    dd ?
  988.              _32767  dd ?
  989.              state   rb 108
  990.            endl
  991.  
  992.         mov     [_600], 0x44160000  ;600.0
  993.         mov     [_32767], 32767
  994.  
  995.         lea     ebx, [state]
  996.         fnsave  [ebx]
  997.  
  998.         stdcall minw, [l_vol], [vol_max]
  999.         stdcall maxw, eax, [vol_min]
  1000.         mov     [l_vol], eax
  1001.         mov     [edx+STREAM.l_vol], eax
  1002.         stdcall minw, [r_vol], [vol_max+4]
  1003.         stdcall maxw, eax, [vol_min+4]
  1004.         mov     [r_vol], eax
  1005.         mov     [edx+STREAM.r_vol], eax
  1006.  
  1007.         stdcall minw, [pan], [pan_max]
  1008.         stdcall maxw, eax, [vol_min]
  1009.         mov     [edx+STREAM.pan], eax
  1010.  
  1011.         cmp     word [edx+STREAM.pan], 0
  1012.         jl      @f
  1013.  
  1014.         mov     ebx, [l_vol]
  1015.         sub     ebx, eax
  1016.         stdcall minw, ebx, [vol_max]
  1017.         stdcall maxw, eax, [vol_min]
  1018.         mov     [l_vol], eax
  1019.         jmp     .calc_amp
  1020. @@:
  1021.         mov     ebx, [r_vol]
  1022.         add     ebx, [pan]
  1023.         stdcall minw, ebx, [vol_max+4]
  1024.         stdcall maxw, eax, [vol_min+4]
  1025.         mov     [r_vol], eax
  1026. .calc_amp:
  1027.         emms
  1028.         fild    word [l_vol]
  1029.  
  1030.         call    .calc
  1031.  
  1032.         fistp   word [edx+STREAM.l_amp]
  1033.         fstp    dword [edx+STREAM.l_amp_f]
  1034.         fstp    st0
  1035.  
  1036.         fild    word [r_vol]
  1037.  
  1038.         call    .calc
  1039.  
  1040.         fistp   word [edx+STREAM.r_amp]
  1041.         fstp    dword [edx+STREAM.r_amp_f]
  1042.         fstp    st0
  1043.  
  1044.         fnclex
  1045.         lea     ebx, [state]
  1046.         frstor  [ebx]
  1047.  
  1048.         xor     eax, eax
  1049.         inc     eax
  1050.         ret
  1051. .calc:
  1052.         fdiv    dword [_600]
  1053.         fld     st0
  1054.         frndint
  1055.         fxch    st1
  1056.         fsub    st, st1
  1057.         f2xm1
  1058.         fld1
  1059.         faddp   st1, st0
  1060.         fscale
  1061.         fld     st0
  1062.         fimul   dword [_32767]
  1063.         ret     0
  1064. endp
  1065.  
  1066.  
  1067. align 4
  1068. proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword
  1069.  
  1070.         mov     edx, [str]
  1071.         mov     eax, [p_lvol]
  1072.         movsx   ecx, word [edx+STREAM.l_vol]
  1073.         mov     [eax], ecx
  1074.  
  1075.         mov     eax, [p_rvol]
  1076.         movsx   ecx, word [edx+STREAM.r_vol]
  1077.         mov     [eax], ecx
  1078.         xor     eax, eax
  1079.         ret
  1080. endp
  1081.  
  1082. align 4
  1083. proc SetBufferPan stdcall, str:dword,pan:dword
  1084.  
  1085.         mov     edx, [str]
  1086.         stdcall set_vol_param, [edx+STREAM.l_vol], \
  1087.                 [edx+STREAM.r_vol],[pan]
  1088.         ret
  1089. endp
  1090.  
  1091. ; for static and ring buffers only
  1092.  
  1093. align 4
  1094. proc play_buffer stdcall, str:dword, flags:dword
  1095.  
  1096.         mov     ebx, [str]
  1097.         mov     eax, [ebx+STREAM.format]
  1098.         test    eax, PCM_OUT
  1099.         jnz     .fail
  1100.  
  1101.         cmp     ax, PCM_ALL
  1102.         je      .fail
  1103.  
  1104.         mov     [ebx+STREAM.flags], SND_PLAY
  1105.         cmp     [eng_state], SND_PLAY
  1106.         je      .done
  1107.  
  1108.         stdcall dev_play, [hSound]
  1109.         mov     [eng_state], SND_PLAY
  1110. .done:
  1111.         test    [flags], PLAY_SYNC
  1112.         jz      @F
  1113.  
  1114.         mov     edx, [str]
  1115. .wait:
  1116.         mov     eax, [edx+STREAM.notify_event]
  1117.         mov     ebx, [edx+STREAM.notify_id]
  1118.         call    WaitEvent   ;eax ebx
  1119.  
  1120.         mov     edx, [str]
  1121.         cmp     [edx+STREAM.flags], SND_STOP
  1122.         jne     .wait
  1123. @@:
  1124.         xor     eax, eax
  1125.         ret
  1126. .fail:
  1127.         or      eax, -1
  1128.         ret
  1129. endp
  1130.  
  1131. ; for static and ring buffers only
  1132.  
  1133. align 4
  1134. proc stop_buffer stdcall, str:dword
  1135.  
  1136.         mov     edx, [str]
  1137.         test    [edx+STREAM.format], PCM_STATIC+PCM_RING
  1138.         jz      .fail
  1139.  
  1140.         mov     [edx+STREAM.flags], SND_STOP
  1141.  
  1142. ;           stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
  1143.  
  1144.         mov     eax, [edx+STREAM.notify_event]
  1145.         mov     ebx, [edx+STREAM.notify_id]
  1146.         call    ClearEvent   ;eax ebx
  1147.  
  1148.         xor     eax, eax
  1149.         ret
  1150. .fail:
  1151.         or      eax, -1
  1152.         ret
  1153. endp
  1154.  
  1155. ; param
  1156. ;  eax= mix_list
  1157.  
  1158. align 4
  1159. do_mix_list:
  1160.  
  1161.         xor     edx, edx
  1162.         mov     esi, str.fd-FD_OFFSET
  1163.         mov     ebx, [esi+STREAM.str_fd]
  1164. @@:
  1165.         cmp     ebx, esi
  1166.         je      .done
  1167.  
  1168.         cmp     [ebx+STREAM.magic], 'WAVE'
  1169.         jne     .next
  1170.  
  1171.         cmp     [ebx+STREAM.size], STREAM.sizeof
  1172.         jne     .next
  1173.  
  1174.         cmp     [ebx+STREAM.flags], SND_PLAY;
  1175.         jne     .next
  1176.  
  1177.         mov     ecx, [ebx+STREAM.out_count]
  1178.         test    ecx, ecx
  1179.         jnz     .l1
  1180.  
  1181.         test    [ebx+STREAM.format], PCM_RING
  1182.         jnz     .next
  1183.         mov     [ebx+STREAM.flags], SND_STOP
  1184.         jmp     .next
  1185. .l1:
  1186.         cmp     ecx, 512
  1187.         jae     .add_buff
  1188.  
  1189.         mov     edi, [ebx+STREAM.out_rp]
  1190.         add     edi, ecx
  1191.         sub     ecx, 512
  1192.         neg     ecx
  1193.         push    eax
  1194.         xor     eax, eax
  1195.         cld
  1196.         rep stosb
  1197.         pop     eax
  1198.  
  1199.         mov     [ebx+STREAM.out_count], 512
  1200.  
  1201. .add_buff:
  1202.         mov     ecx, [ebx+STREAM.out_rp]
  1203.         mov     [eax], ecx
  1204.  
  1205. if USE_SSE2_MIXER
  1206.         mov     edi, dword [ebx+STREAM.l_amp_f]
  1207.         mov     [eax+4], edi
  1208.         mov     edi, dword [ebx+STREAM.r_amp_f]
  1209.         mov     [eax+8], edi
  1210. else
  1211.         mov     edi, dword [ebx+STREAM.l_amp]
  1212.         mov     [eax+4], edi
  1213. end if
  1214.         add     [ebx+STREAM.out_rp], 512
  1215.         sub     [ebx+STREAM.out_count], 512
  1216.  
  1217.         add     eax, 12
  1218.         inc     edx
  1219. .next:
  1220.         mov     ebx, [ebx+STREAM.str_fd]
  1221.         jmp     @B
  1222. .done:
  1223.         mov     eax, edx
  1224.         ret
  1225.  
  1226. align 4
  1227. prepare_playlist:
  1228.  
  1229.         xor     edx, edx
  1230.         mov     [play_count], edx
  1231.         mov     esi, str.fd-FD_OFFSET
  1232.         mov     edi, [esi+STREAM.str_fd]
  1233. @@:
  1234.         cmp     edi, esi
  1235.         je      .done
  1236.  
  1237.         cmp     [edi+STREAM.magic], 'WAVE'
  1238.         jne     .next
  1239.  
  1240.         cmp     [edi+STREAM.size], STREAM.sizeof
  1241.         jne     .next
  1242.  
  1243.         cmp     [edi+STREAM.flags], SND_PLAY;
  1244.         jne     .next
  1245.  
  1246.         mov     [play_list+edx], edi
  1247.         inc     [play_count]
  1248.         add     edx, 4
  1249. .next:
  1250.         mov     edi, [edi+STREAM.str_fd]
  1251.         jmp     @B
  1252. .done:
  1253.         ret
  1254.  
  1255. align 4
  1256. proc set_handler stdcall, hsrv:dword, handler_proc:dword
  1257.            locals
  1258.              handler    dd ?
  1259.              io_code    dd ?
  1260.              input      dd ?
  1261.              inp_size   dd ?
  1262.              output     dd ?
  1263.              out_size   dd ?
  1264.              val        dd ?
  1265.            endl
  1266.  
  1267.         mov     eax, [hsrv]
  1268.         lea     ecx, [handler_proc]
  1269.         xor     ebx, ebx
  1270.  
  1271.         mov     [handler], eax
  1272.         mov     [io_code], DEV_CALLBACK
  1273.         mov     [input], ecx
  1274.         mov     [inp_size], 4
  1275.         mov     [output], ebx
  1276.         mov     [out_size], 0
  1277.  
  1278.         lea     eax, [handler]
  1279.         stdcall ServiceHandler, eax
  1280.         ret
  1281. endp
  1282.  
  1283. align 4
  1284. proc dev_play stdcall, hsrv:dword
  1285.            locals
  1286.              handle     dd ?
  1287.              io_code    dd ?
  1288.              input      dd ?
  1289.              inp_size   dd ?
  1290.              output     dd ?
  1291.              out_size   dd ?
  1292.              val        dd ?
  1293.            endl
  1294.  
  1295.         mov     eax, [hsrv]
  1296.         xor     ebx, ebx
  1297.  
  1298.         mov     [handle], eax
  1299.         mov     [io_code], DEV_PLAY
  1300.         mov     [input], ebx
  1301.         mov     [inp_size], ebx
  1302.         mov     [output], ebx
  1303.         mov     [out_size], ebx
  1304.  
  1305.         lea     eax, [handle]
  1306.         stdcall ServiceHandler, eax
  1307.         ret
  1308. endp
  1309.  
  1310. if 0
  1311. align 4
  1312. dword2str:
  1313.         mov     esi, hex_buff
  1314.         mov     ecx, -8
  1315. @@:
  1316.         rol     eax, 4
  1317.         mov     ebx, eax
  1318.         and     ebx, 0x0F
  1319.         mov     bl, [ebx+hexletters]
  1320.         mov     [8+esi+ecx], bl
  1321.         inc     ecx
  1322.         jnz     @B
  1323.         ret
  1324.  
  1325. hexletters   db '0123456789ABCDEF'
  1326. hex_buff     db 8 dup(0),13,10,0
  1327.  
  1328. end if
  1329.  
  1330. include 'mixer.asm'
  1331. include 'mix_mmx.inc'
  1332. include 'mix_sse2.inc'
  1333.  
  1334. ;if USE_SSE
  1335. ; include 'mix_sse.inc'
  1336. ;end if
  1337.  
  1338. align 16
  1339. resampler_params:
  1340.      ;r_size    r_dt   resampler_func
  1341.      dd 0,0,0                                  ; 0  PCM_ALL
  1342.      dd 16384,      0, copy_stream    ; 1  PCM_2_16_48
  1343.      dd  8192,      0, m16_stereo     ; 2  PCM_1_16_48
  1344.  
  1345.      dd 16384,  30109, resample_2     ; 3  PCM_2_16_44
  1346.      dd  8192,  30109, resample_1     ; 4  PCM_1_16_44
  1347.  
  1348.      dd 16384,  21846, resample_2     ; 5  PCM_2_16_32
  1349.      dd  8192,  21846, resample_1     ; 6  PCM_1_16_32
  1350.  
  1351.      dd 16384,  16384, resample_2     ; 7  PCM_2_16_24
  1352.      dd  8192,  16384, resample_1     ; 8  PCM_1_16_24
  1353.  
  1354.      dd  8192,  15052, resample_2     ; 9  PCM_2_16_22
  1355.      dd  4096,  15052, resample_1     ;10  PCM_1_16_22
  1356.  
  1357.      dd  8192,  10923, resample_2     ;11  PCM_2_16_16
  1358.      dd  4096,  10923, resample_1     ;12  PCM_1_16_16
  1359.  
  1360.      dd  8192,   8192, resample_2     ;13  PCM_2_16_12
  1361.      dd  4096,   8192, resample_1     ;14  PCM_1_16_12
  1362.  
  1363.      dd  4096,   7527, resample_2     ;15  PCM_2_16_11
  1364.      dd  2048,   7527, resample_1     ;16  PCM_1_16_11
  1365.  
  1366.      dd  4096,   5462, resample_2     ;17  PCM_2_16_8
  1367.      dd  2048,   5462, resample_1     ;18  PCM_1_16_8
  1368.  
  1369.      dd 16384,      0, s8_stereo      ;19  PCM_2_8_48
  1370.      dd  8192,      0, m8_stereo      ;20  PCM_1_8_48
  1371.  
  1372.      dd  8192,  30109, resample_28    ;21  PCM_2_8_44
  1373.      dd  4096,  30109, resample_18    ;22  PCM_1_8_44
  1374.  
  1375.      dd  8192,  21846, resample_28    ;23  PCM_2_8_32
  1376.      dd  4096,  21846, resample_18    ;24  PCM_1_8_32
  1377.  
  1378.      dd  8192,  16384, resample_28    ;25  PCM_2_8_24
  1379.      dd  4096,  16384, resample_18    ;26  PCM_1_8_24
  1380.  
  1381.      dd  4096,  15052, resample_28    ;27  PCM_2_8_22
  1382.      dd  2048,  15052, resample_18    ;28  PCM_1_8_22
  1383.  
  1384.      dd  4096,  10923, resample_28    ;29  PCM_2_8_16
  1385.      dd  2048,  10923, resample_18    ;30  PCM_1_8_16
  1386.  
  1387.      dd  4096,   8192, resample_28    ;31  PCM_2_8_12
  1388.      dd  2048,   8192, resample_18    ;32  PCM_1_8_12
  1389.  
  1390.      dd  2048,   7527, resample_28    ;33  PCM_2_8_11
  1391.      dd  1024,   7527, resample_18    ;34  PCM_1_8_11
  1392.  
  1393.      dd  2048,   5462, resample_28    ;35  PCM_2_8_8
  1394.      dd  1024,   5462, resample_18    ;36  PCM_1_8_8
  1395.  
  1396. m7            dw 0x8000,0x8000,0x8000,0x8000
  1397. mm80          dq 0x8080808080808080
  1398. mm_mask       dq 0xFF00FF00FF00FF00
  1399.  
  1400. vol_max       dd 0x00000000,0x00000000
  1401. vol_min       dd 0x0000D8F0,0x0000D8F0
  1402. pan_max       dd 0x00002710,0x00002710
  1403.  
  1404. ;stream_map    dd 0xFFFF       ; 16
  1405. version       dd (5 shl 16) or SOUND_VERSION
  1406.  
  1407. szInfinity    db 'INFINITY',0
  1408. szSound       db 'SOUND',0
  1409.  
  1410. if DEBUG
  1411. msgFail       db 'Sound service not loaded',13,10,0
  1412. msgPlay       db 'Play buffer',13,10,0
  1413. msgStop       db 'Stop',13,10,0
  1414. msgUser       db 'User callback',13,10,0
  1415. msgMem        db 'Not enough memory',13,10,0
  1416. msgDestroy    db 'Destroy sound buffer', 13,10,0
  1417. msgWaveout    db 'Play waveout', 13,10,0
  1418. msgSetVolume  db 'Set volume',13,10,0
  1419. end if
  1420.  
  1421. section '.data' data readable writable align 16
  1422.  
  1423. play_list     rd 16
  1424. mix_input     rd 16
  1425. play_count    rd 1
  1426. hSound        rd 1
  1427. eng_state     rd 1
  1428. mix_buff      rd 1
  1429. mix_buff_map  rd 1
  1430. str.fd        rd 1
  1431. str.bk        rd 1
  1432.  
  1433. mix_2_core    rd 1
  1434. mix_3_core    rd 1
  1435. mix_4_core    rd 1
  1436.