Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2006-2011. 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+4]
  352.         mov     ebx, [ebx+8]
  353.  
  354.         pushfd
  355.         cli
  356.         mov     dword [edx+STREAM.time_base], eax
  357.         mov     dword [edx+STREAM.time_base+4], ebx
  358.         xor     eax, eax
  359.         mov     dword [edx+STREAM.time_stamp], eax
  360.         mov     dword [edx+STREAM.time_stamp+4], eax
  361.         popfd
  362.  
  363.         ret
  364.  
  365. align 4
  366. .snd_gettimestamp:
  367.         cmp     [edi+out_size], 8
  368.         jne     .fail
  369.  
  370.         pushfd
  371.         cli
  372.  
  373.         xor     ebx, ebx
  374.         push    48
  375.         push    ebx            ; local storage
  376.  
  377.         cmp     [edx+STREAM.flags], SND_STOP
  378.         je      @F
  379.  
  380.         mov     eax, esp
  381.  
  382.         push ebx
  383.         push ecx
  384.         push    edx
  385.         push esi
  386.         push    edi
  387.  
  388.         push    4              ;.out_size
  389.         push    eax            ;.output
  390.         push    ebx            ;.inp_size
  391.         push    ebx            ;.input
  392.         push    DEV_GET_POS    ;.code
  393.         push    dword [hSound] ;.handle
  394.         mov     eax, esp
  395.  
  396.         stdcall ServiceHandler, eax
  397.         add     esp, 6*4
  398.  
  399.         pop     edi
  400.         pop esi
  401.         pop     edx
  402.         pop ecx
  403.         pop ebx
  404.  
  405.         test    eax, eax
  406.         jz      @F
  407.  
  408.         mov     dword [esp], 0  ; clear offset
  409. @@:
  410.         mov     edi, [edi+output]
  411.  
  412.         emms
  413.         fild    qword [edx+STREAM.time_stamp]
  414.         fiadd   dword [esp]     ; primary buffer offset
  415.         fidiv   dword [esp+4]   ; total_samples / frequency
  416.         fadd    qword [edx+STREAM.time_base]
  417.         fstp    qword [edi]
  418.         add     esp, 8
  419.  
  420.         popfd
  421.  
  422.         xor     eax, eax
  423.         ret
  424. endp
  425.  
  426.  
  427. restore   handle
  428. restore   io_code
  429. restore   input
  430. restore   inp_size
  431. restore   output
  432. restore   out_size
  433.  
  434. align 4
  435. proc CreateBuffer stdcall, format:dword, size:dword
  436.            locals
  437.         str     dd ?
  438.              ring_size   dd ?
  439.              ring_pages  dd ?
  440.            endl
  441.  
  442.         mov     eax, [format]
  443.         cmp     ax, PCM_1_8_8
  444.         ja      .fail
  445.  
  446.         test    eax, PCM_OUT
  447.         jnz     .test_out
  448.         test    eax, PCM_RING
  449.         jnz     .test_ring
  450. ;staic
  451.         test    eax, PCM_STATIC
  452.         jz      .test_out                 ;use PCM_OUT as default format
  453.         jmp     .test_ok
  454. .test_out:
  455.         test    eax, PCM_RING+PCM_STATIC
  456.         jnz     .fail
  457.         or      [format], PCM_OUT         ;force set
  458.         jmp     .test_ok
  459. .test_ring:
  460.         test    eax, PCM_OUT+PCM_STATIC
  461.         jnz     .fail
  462. .test_ok:
  463.  
  464.         call    GetPid
  465.         mov     ebx, eax
  466.         mov     eax, STREAM.sizeof
  467.  
  468.         call    CreateObject
  469.         test    eax, eax
  470.         jz      .fail
  471.         mov     [str], eax
  472.  
  473.         mov     ebx, [format]
  474.         mov     [eax+STREAM.format], ebx
  475.  
  476.         xor     ecx, ecx
  477.         movzx   ebx, bx
  478.         cmp     ebx, 19
  479.         jb      @f
  480.         mov     ecx, 0x80808080
  481. @@:
  482.         mov     [eax+STREAM.r_silence], ecx
  483.  
  484.         shl     ebx, 2
  485.         lea     ebx, [ebx+ebx*2]    ;ebx*=12
  486.  
  487.         mov     ecx, [resampler_params+ebx]
  488.         mov     edx, [resampler_params+ebx+4]
  489.         mov     esi, [resampler_params+ebx+8]
  490.  
  491.         mov     [eax+STREAM.r_size], ecx
  492.         mov     [eax+STREAM.r_dt], edx
  493.         mov     [eax+STREAM.resample], esi
  494.         xor     ecx, ecx
  495.         mov     [eax+STREAM.l_vol], ecx
  496.         mov     [eax+STREAM.r_vol], ecx
  497.         mov     dword [eax+STREAM.l_amp], 0x7FFF7FFF
  498.         mov     [eax+STREAM.pan], ecx
  499.  
  500.         test    [format], PCM_STATIC
  501.         jnz     .static
  502.  
  503. ; ring and waveout
  504.  
  505.         mov     ebx, 0x10000
  506.         test    [format], PCM_RING
  507.         jz      .waveout
  508.  
  509.         mov     ebx, [eax+STREAM.r_size]
  510.         add     ebx, 4095
  511.         and     ebx, -4096
  512.         add     ebx, ebx
  513. .waveout:
  514.         mov     [ring_size], ebx
  515.         mov     eax, ebx
  516.         shr     ebx, 12
  517.         mov     [ring_pages], ebx
  518.  
  519.         stdcall CreateRingBuffer, eax, PG_SW
  520.  
  521.         mov     edi, [str]
  522.         mov     ecx, [ring_size]
  523.         mov     [edi+STREAM.in_base], eax
  524.         mov     [edi+STREAM.in_size], ecx
  525.         add     eax, 128
  526.         mov     [edi+STREAM.in_wp], eax
  527.         mov     [edi+STREAM.in_rp], eax
  528.         mov     [edi+STREAM.in_count], 0
  529.  
  530.         mov     [edi+STREAM.in_free], ecx
  531.         add     eax, ecx
  532.         mov     [edi+STREAM.in_top], eax
  533.  
  534.         jmp     .out_buff
  535. .static:
  536.         mov     ecx, [size]
  537.         add     ecx, 128         ;resampler required
  538.         mov     [eax+STREAM.in_size], ecx
  539.         stdcall KernelAlloc, ecx
  540.  
  541.         mov     edi, [str]
  542.         mov     [edi+STREAM.in_base], eax
  543.         add     eax, 128
  544.         mov     [edi+STREAM.in_wp], eax
  545.         mov     [edi+STREAM.in_rp], eax
  546.         mov     ebx, [size]
  547.         mov     [edi+STREAM.in_count], ebx
  548.         mov     [edi+STREAM.in_free], ebx
  549.         add     eax, ebx
  550.         mov     [edi+STREAM.in_top], eax
  551.  
  552. .out_buff:
  553.         stdcall AllocKernelSpace, dword 128*1024
  554.  
  555.         mov     edi, [str]
  556.         xor     ebx, ebx
  557.  
  558.         mov     [edi+STREAM.out_base], eax
  559.         mov     [edi+STREAM.out_wp], eax
  560.         mov     [edi+STREAM.out_rp], eax
  561.         mov     [edi+STREAM.out_count], ebx
  562.         add     eax, 64*1024
  563.         mov     [edi+STREAM.out_top], eax
  564.  
  565.         mov     dword [edi+STREAM.time_base], ebx
  566.         mov     dword [edi+STREAM.time_base+4], ebx
  567.  
  568.         mov     dword [edi+STREAM.time_stamp], ebx
  569.         mov     dword [edi+STREAM.time_stamp+4], ebx
  570.         mov     dword [edi+STREAM.last_ts], ebx
  571.  
  572.         stdcall AllocPages, dword 64/4
  573.         mov     edi, [str]
  574.         mov     ebx, [edi+STREAM.out_base]
  575.         mov     ecx, 16
  576.         or      eax, PG_SW
  577.         push    eax
  578.         push    ebx
  579.         call    CommitPages ;eax, ebx, ecx
  580.         mov     ecx, 16
  581.         pop     ebx
  582.         pop     eax
  583.         add     ebx, 64*1024
  584.         call    CommitPages    ;double mapped
  585.  
  586.         mov     edi, [str]
  587.         mov     ecx, [edi+STREAM.in_top]
  588.         mov     edi, [edi+STREAM.in_base]
  589.         sub     ecx, edi
  590.         xor     eax, eax
  591.         shr     ecx, 2
  592.         cld
  593.         rep stosd
  594.  
  595.         mov     edi, [str]
  596.         mov     edi, [edi+STREAM.out_base]
  597.         mov     ecx, (64*1024)/4
  598.         rep stosd
  599.  
  600.         xor     esi, esi
  601.         mov     ecx, MANUAL_DESTROY
  602.         call    CreateEvent
  603.  
  604.         mov     ebx, [str]
  605.         mov     [ebx+STREAM.notify_event], eax
  606.         mov     [ebx+STREAM.notify_id], edx
  607.  
  608.         mov     [ebx+STREAM.magic], 'WAVE'
  609.         mov     [ebx+STREAM.destroy], DestroyBuffer.destroy
  610.         mov     [ebx+STREAM.size], STREAM.sizeof
  611.         mov     [ebx+STREAM.flags], SND_STOP
  612.  
  613.         pushf
  614.         cli
  615.         mov     eax, str.fd-FD_OFFSET
  616.         mov     edx, [eax+STREAM.str_fd]
  617.         mov     [ebx+STREAM.str_fd], edx
  618.         mov     [ebx+STREAM.str_bk], eax
  619.         mov     [eax+STREAM.str_fd], ebx
  620.         mov     [edx+STREAM.str_bk], ebx
  621.         popf
  622.  
  623.         xor     eax, eax
  624.         ret
  625. .fail:
  626.         xor     ebx, ebx
  627.         or      eax, -1
  628.         ret
  629. endp
  630.  
  631. ;param
  632. ; eax= buffer handle
  633.  
  634. align 4
  635. DestroyBuffer:
  636.            .handle  equ esp       ;local
  637.  
  638.         mov     [eax+STREAM.flags], SND_STOP
  639. .destroy:
  640.         push    eax
  641.  
  642.         pushfd
  643.         cli
  644.         mov     ebx, [eax+STREAM.str_fd]
  645.         mov     ecx, [eax+STREAM.str_bk]
  646.         mov     [ebx+STREAM.str_bk], ecx
  647.         mov     [ecx+STREAM.str_fd], ebx
  648.         popf
  649.  
  650.         stdcall KernelFree, [eax+STREAM.in_base]
  651.         mov     eax, [.handle]
  652.         stdcall KernelFree, [eax+STREAM.out_base]
  653.  
  654.         pop     eax              ;restore stack
  655.         call    DestroyObject    ;eax= stream
  656.         xor     eax, eax
  657.         ret
  658. .fail:
  659.         or      eax, -1
  660.         ret
  661. restore .handle
  662.  
  663. align 4
  664. proc SetFormat stdcall, str:dword, format:dword
  665.  
  666.         cmp     word [format], PCM_1_8_8
  667.         ja      .fail
  668.  
  669.         mov     edx, [str]
  670.         mov     [edx+STREAM.flags], SND_STOP
  671.  
  672.         test    [edx+STREAM.format], PCM_RING
  673.         jnz     .fail
  674.  
  675. ;           mov eax,[edx+STREAM.out_base]
  676. ;           mov [edx+STREAM.out_wp], eax
  677. ;           mov [edx+STREAM.out_rp], eax
  678. ;           mov [edx+STREAM.out_count], 0
  679.  
  680.         movzx   eax, word [format]
  681.         mov     word [edx+STREAM.format], ax
  682.  
  683.         xor     ebx, ebx
  684.         cmp     eax, 19
  685.         jb      @f
  686.         mov     ebx, 0x80808080
  687. @@:
  688.         mov     [edx+STREAM.r_silence], ebx
  689.  
  690.         shl     eax, 2
  691.         lea     eax, [eax+eax*2]    ;eax*=12
  692.  
  693.         mov     edi, [resampler_params+eax]
  694.         mov     ecx, [resampler_params+eax+4]
  695.         mov     ebx, [resampler_params+eax+8]
  696.  
  697.         mov     [edx+STREAM.r_size], edi
  698.         mov     [edx+STREAM.r_dt], ecx
  699.         mov     [edx+STREAM.resample], ebx
  700.  
  701.         mov     edi, [edx+STREAM.in_base]
  702.         mov     ecx, 128/4
  703.         mov     eax, [edx+STREAM.r_silence]
  704.         cld
  705.         rep stosd
  706.         xor     eax, eax
  707.         ret
  708. .fail:
  709.         or      eax, -1
  710.         ret
  711. endp
  712.  
  713. ; for static buffers only
  714. ; use waveout for streams
  715.  
  716. align 4
  717. proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
  718.  
  719.         mov     edx, [str]
  720.         test    [edx+STREAM.format], PCM_OUT
  721.         jnz     .fail
  722.  
  723.         mov     esi, [src]
  724.         mov     edi, [offs]
  725.         add     edi, [edx+STREAM.in_base]
  726.         add     edi, 128
  727.  
  728.         cmp     edi, [edx+STREAM.in_top]
  729.         jae     .fail
  730.  
  731.         mov     ecx, [size]
  732.         lea     ebx, [ecx+edi]
  733.         sub     ebx, [edx+STREAM.in_top]
  734.         jb      @F
  735.         sub     ecx, ebx
  736. @@:
  737.         shr     ecx, 2
  738.         cld
  739.         rep movsd
  740.         xor     eax, eax
  741.         ret
  742. .fail:
  743.         or      eax, -1
  744.         ret
  745. endp
  746.  
  747. ; for stream buffers only
  748.  
  749. align 4
  750. proc wave_out stdcall, str:dword,src:dword,size:dword
  751.            locals
  752.              state_saved  dd ?
  753.              fpu_state    rb 528
  754.            endl
  755.  
  756.         mov     edx, [str]
  757.         mov     eax, [edx+STREAM.format]
  758.         test    eax, PCM_OUT
  759.         jz      .fail
  760.  
  761.         cmp     ax, PCM_ALL
  762.         je      .fail
  763.  
  764.         mov     esi, [src]
  765.         test    esi, esi
  766.         jz      .fail
  767.  
  768.         cmp     esi, OS_BASE
  769.         jae     .fail
  770.  
  771.         mov     [state_saved], 0
  772.  
  773. .main_loop:
  774.         mov     edx, [str]
  775.  
  776.         mov     ebx, [size]
  777.         test    ebx, ebx
  778.         jz      .done
  779.  
  780.         cmp     [edx+STREAM.flags], SND_STOP
  781.         jne     .fill
  782.  
  783.         mov     edi, [edx+STREAM.in_base]
  784.         mov     ecx, 128/4
  785.         mov     eax, [edx+STREAM.r_silence]
  786.         cld
  787.         rep stosd
  788.  
  789.         mov     ecx, [edx+STREAM.in_size]
  790.         sub     ecx, 128
  791.         mov     [edx+STREAM.in_wp], edi
  792.         mov     [edx+STREAM.in_rp], edi
  793.         mov     [edx+STREAM.in_count], 0
  794.         mov     [edx+STREAM.in_free], ecx
  795.  
  796.         mov     eax, [edx+STREAM.out_base]
  797.         mov     [edx+STREAM.out_wp], eax
  798.         mov     [edx+STREAM.out_rp], eax
  799.         mov     [edx+STREAM.out_count], 0
  800. .fill:
  801.         cli
  802.  
  803.         mov     ecx, [edx+STREAM.in_free]
  804.         test    ecx, ecx
  805.         jz      .wait
  806.  
  807.         cmp     ecx, ebx
  808.         jbe     @F
  809.  
  810.         mov     ecx, ebx
  811. @@:
  812.         sub     [size], ecx
  813.         add     [edx+STREAM.in_count], ecx
  814.         sub     [edx+STREAM.in_free], ecx
  815.  
  816.         shr     ecx, 2
  817.         mov     edi, [edx+STREAM.in_wp]
  818.         mov     esi, [src]
  819.         cld
  820.         rep movsd
  821.  
  822.         mov     [src], esi
  823.         cmp     edi, [edx+STREAM.in_top]
  824.         jb      @F
  825.         sub     edi, [edx+STREAM.in_size]
  826. @@:
  827.         mov     [edx+STREAM.in_wp], edi
  828.  
  829.         cmp     [edx+STREAM.out_count], 32768
  830.         jae     .skip
  831.  
  832.         cmp     [state_saved], 0
  833.         jne     @F
  834.         lea     eax, [fpu_state+15]
  835.         and     eax, -16
  836.         call    FpuSave
  837.         mov     [state_saved], 1
  838. @@:
  839.         stdcall refill, edx
  840.  
  841. .skip:
  842.         sti
  843.         mov     edx, [str]
  844.         mov     [edx+STREAM.flags], SND_PLAY
  845.         cmp     [eng_state], SND_PLAY
  846.         je      .main_loop
  847.  
  848.         stdcall dev_play, [hSound]
  849.         mov     [eng_state], SND_PLAY
  850.         jmp     .main_loop
  851. .wait:
  852.         sti
  853.         mov     edx, [str]
  854.         mov     eax, [edx+STREAM.notify_event]
  855.         mov     ebx, [edx+STREAM.notify_id]
  856.         call    WaitEvent   ;eax ebx
  857.         jmp     .main_loop
  858. .done:
  859.         cmp     [state_saved], 1
  860.         jne     @F
  861.  
  862.         lea     eax, [fpu_state+15]
  863.         and     eax, -16
  864.         call    FpuRestore
  865. @@:
  866.         xor     eax, eax
  867.         ret
  868. .fail:
  869.         or      eax, -1
  870.         ret
  871. endp
  872.  
  873. ; both static and stream
  874. ; reset all but not clear buffers
  875.  
  876.  
  877. ; flags reserved
  878. ;  RESET_INPUT  equ 1   ;reserved reset and clear input buffer
  879. ;  RESET_OUTPUT equ 2   ;reserved reset and clear output buffer
  880. ;  RESET_ALL    equ 3
  881.  
  882.  
  883. align 4
  884. proc ResetBuffer stdcall, str:dword, flags:dword
  885.  
  886.         mov     edx, [str]
  887.         mov     [edx+STREAM.flags], SND_STOP
  888.  
  889.         mov     edi, [edx+STREAM.in_base]
  890.         mov     ecx, 128/4
  891.         mov     eax, [edx+STREAM.r_silence]
  892.         cld
  893.         rep stosd
  894.  
  895.         mov     [edx+STREAM.in_wp], edi
  896.         mov     [edx+STREAM.in_rp], edi
  897.  
  898.         test    [edx+STREAM.flags], PCM_STATIC
  899.         jnz     .static
  900.         mov     [edx+STREAM.in_count], 0
  901.         jmp     @F
  902. .static:
  903.         mov     eax, [edx+STREAM.in_size]
  904.         mov     [edx+STREAM.in_count], eax
  905. @@:
  906.  
  907.         mov     eax, [edx+STREAM.in_size]
  908.         sub     eax, 128
  909.         mov     [edx+STREAM.in_free], eax
  910.  
  911.         xor     eax, eax
  912.         mov     ebx, [edx+STREAM.out_base]
  913.         mov     [edx+STREAM.out_wp], ebx
  914.         mov     [edx+STREAM.out_rp], ebx
  915.         mov     [edx+STREAM.out_count], eax
  916.         ret
  917. .fail:
  918.         or      eax, -1
  919.         ret
  920. endp
  921.  
  922. ; for static buffers only
  923.  
  924. align 4
  925. proc SetBufferPos stdcall, str:dword, pos:dword
  926.  
  927.         mov     edx, [str]
  928.         test    [edx+STREAM.format], PCM_STATIC
  929.         jz      .fail
  930.  
  931.         mov     [edx+STREAM.flags], SND_STOP
  932.  
  933.         mov     eax, [pos]
  934.         add     eax, [edx+STREAM.in_base]
  935.         mov     ebx, [edx+STREAM.in_top]
  936.         add     eax, 128
  937.  
  938.         cmp     eax, ebx
  939.         jae     .fail
  940.  
  941.         mov     [edx+STREAM.in_rp], eax
  942.         sub     ebx, eax
  943.         mov     [edx+STREAM.in_count], ebx
  944.         xor     eax, eax
  945.         ret
  946. .fail:
  947.         or      eax, -1
  948.         ret
  949. endp
  950.  
  951. align 4
  952. proc GetBufferPos stdcall, str:dword
  953.  
  954.         mov     edx, [str]
  955.         test    [edx+STREAM.format], PCM_STATIC
  956.         jz      .fail
  957.  
  958.         mov     ebx, [edx+STREAM.in_rp]
  959.         sub     ebx, [edx+STREAM.in_base]
  960.         sub     ebx, 128
  961.         xor     eax, eax
  962.         ret
  963. .fail:
  964.         xor     ebx, ebx
  965.         or      eax, -1
  966.         ret
  967. endp
  968.  
  969. ; both
  970.  
  971. align 4
  972. proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword
  973.  
  974.         mov     edx, [str]
  975.         stdcall set_vol_param, [l_vol], [r_vol], [edx+STREAM.pan]
  976.         ret
  977. endp
  978.  
  979.  
  980. proc minw stdcall, arg1:dword, arg2:dword
  981.         mov     ax, word [arg1]
  982.         cmp     ax, word [arg2]
  983.         jle     @f
  984.         mov     eax, [arg2]
  985. @@:
  986.         ret
  987. endp
  988.  
  989. proc maxw stdcall, arg1:dword, arg2:dword
  990.         mov     ax, word [arg1]
  991.         cmp     ax, word [arg2]
  992.         jge     @f
  993.         mov     eax, [arg2]
  994. @@:
  995.         ret
  996. endp
  997.  
  998.  
  999. proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword
  1000.            locals
  1001.              _600    dd ?
  1002.              _32767  dd ?
  1003.              state   rb 108
  1004.            endl
  1005.  
  1006.         mov     [_600], 0x44160000  ;600.0
  1007.         mov     [_32767], 32767
  1008.  
  1009.         lea     ebx, [state]
  1010.         fnsave  [ebx]
  1011.  
  1012.         stdcall minw, [l_vol], [vol_max]
  1013.         stdcall maxw, eax, [vol_min]
  1014.         mov     [l_vol], eax
  1015.         mov     [edx+STREAM.l_vol], eax
  1016.         stdcall minw, [r_vol], [vol_max+4]
  1017.         stdcall maxw, eax, [vol_min+4]
  1018.         mov     [r_vol], eax
  1019.         mov     [edx+STREAM.r_vol], eax
  1020.  
  1021.         stdcall minw, [pan], [pan_max]
  1022.         stdcall maxw, eax, [vol_min]
  1023.         mov     [edx+STREAM.pan], eax
  1024.  
  1025.         cmp     word [edx+STREAM.pan], 0
  1026.         jl      @f
  1027.  
  1028.         mov     ebx, [l_vol]
  1029.         sub     ebx, eax
  1030.         stdcall minw, ebx, [vol_max]
  1031.         stdcall maxw, eax, [vol_min]
  1032.         mov     [l_vol], eax
  1033.         jmp     .calc_amp
  1034. @@:
  1035.         mov     ebx, [r_vol]
  1036.         add     ebx, [pan]
  1037.         stdcall minw, ebx, [vol_max+4]
  1038.         stdcall maxw, eax, [vol_min+4]
  1039.         mov     [r_vol], eax
  1040. .calc_amp:
  1041.         emms
  1042.         fild    word [l_vol]
  1043.  
  1044.         call    .calc
  1045.  
  1046.         fistp   word [edx+STREAM.l_amp]
  1047.         fstp    dword [edx+STREAM.l_amp_f]
  1048.         fstp    st0
  1049.  
  1050.         fild    word [r_vol]
  1051.  
  1052.         call    .calc
  1053.  
  1054.         fistp   word [edx+STREAM.r_amp]
  1055.         fstp    dword [edx+STREAM.r_amp_f]
  1056.         fstp    st0
  1057.  
  1058.         fnclex
  1059.         lea     ebx, [state]
  1060.         frstor  [ebx]
  1061.  
  1062.         xor     eax, eax
  1063.         inc     eax
  1064.         ret
  1065. .calc:
  1066.         fdiv    dword [_600]
  1067.         fld     st0
  1068.         frndint
  1069.         fxch    st1
  1070.         fsub    st, st1
  1071.         f2xm1
  1072.         fld1
  1073.         faddp   st1, st0
  1074.         fscale
  1075.         fld     st0
  1076.         fimul   dword [_32767]
  1077.         ret     0
  1078. endp
  1079.  
  1080.  
  1081. align 4
  1082. proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword
  1083.  
  1084.         mov     edx, [str]
  1085.         mov     eax, [p_lvol]
  1086.         movsx   ecx, word [edx+STREAM.l_vol]
  1087.         mov     [eax], ecx
  1088.  
  1089.         mov     eax, [p_rvol]
  1090.         movsx   ecx, word [edx+STREAM.r_vol]
  1091.         mov     [eax], ecx
  1092.         xor     eax, eax
  1093.         ret
  1094. endp
  1095.  
  1096. align 4
  1097. proc SetBufferPan stdcall, str:dword,pan:dword
  1098.  
  1099.         mov     edx, [str]
  1100.         stdcall set_vol_param, [edx+STREAM.l_vol], \
  1101.                 [edx+STREAM.r_vol],[pan]
  1102.         ret
  1103. endp
  1104.  
  1105. ; for static and ring buffers only
  1106.  
  1107. align 4
  1108. proc play_buffer stdcall, str:dword, flags:dword
  1109.  
  1110.         mov     ebx, [str]
  1111.         mov     eax, [ebx+STREAM.format]
  1112.         test    eax, PCM_OUT
  1113.         jnz     .fail
  1114.  
  1115.         cmp     ax, PCM_ALL
  1116.         je      .fail
  1117.  
  1118.         mov     [ebx+STREAM.flags], SND_PLAY
  1119.         cmp     [eng_state], SND_PLAY
  1120.         je      .done
  1121.  
  1122.         stdcall dev_play, [hSound]
  1123.         mov     [eng_state], SND_PLAY
  1124. .done:
  1125.         test    [flags], PLAY_SYNC
  1126.         jz      @F
  1127.  
  1128.         mov     edx, [str]
  1129. .wait:
  1130.         mov     eax, [edx+STREAM.notify_event]
  1131.         mov     ebx, [edx+STREAM.notify_id]
  1132.         call    WaitEvent   ;eax ebx
  1133.  
  1134.         mov     edx, [str]
  1135.         cmp     [edx+STREAM.flags], SND_STOP
  1136.         jne     .wait
  1137. @@:
  1138.         xor     eax, eax
  1139.         ret
  1140. .fail:
  1141.         or      eax, -1
  1142.         ret
  1143. endp
  1144.  
  1145. ; for static and ring buffers only
  1146.  
  1147. align 4
  1148. proc stop_buffer stdcall, str:dword
  1149.  
  1150.         mov     edx, [str]
  1151.         test    [edx+STREAM.format], PCM_STATIC+PCM_RING
  1152.         jz      .fail
  1153.  
  1154.         mov     [edx+STREAM.flags], SND_STOP
  1155.  
  1156. ;           stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
  1157.  
  1158.         mov     eax, [edx+STREAM.notify_event]
  1159.         mov     ebx, [edx+STREAM.notify_id]
  1160.         call    ClearEvent   ;eax ebx
  1161.  
  1162.         xor     eax, eax
  1163.         ret
  1164. .fail:
  1165.         or      eax, -1
  1166.         ret
  1167. endp
  1168.  
  1169. ; param
  1170. ;  eax= mix_list
  1171.  
  1172. align 4
  1173. do_mix_list:
  1174.  
  1175.         xor     edx, edx
  1176.         mov     esi, str.fd-FD_OFFSET
  1177.         mov     ebx, [esi+STREAM.str_fd]
  1178. @@:
  1179.         cmp     ebx, esi
  1180.         je      .done
  1181.  
  1182.         cmp     [ebx+STREAM.magic], 'WAVE'
  1183.         jne     .next
  1184.  
  1185.         cmp     [ebx+STREAM.size], STREAM.sizeof
  1186.         jne     .next
  1187.  
  1188.         cmp     [ebx+STREAM.flags], SND_PLAY;
  1189.         jne     .next
  1190.  
  1191.         mov     ecx, [ebx+STREAM.out_count]
  1192.         test    ecx, ecx
  1193.         jnz     .l1
  1194.  
  1195.         test    [ebx+STREAM.format], PCM_RING
  1196.         jnz     .next
  1197.         mov     [ebx+STREAM.flags], SND_STOP
  1198.         jmp     .next
  1199. .l1:
  1200.         cmp     ecx, 512
  1201.         jae     .add_buff
  1202.  
  1203.         mov     edi, [ebx+STREAM.out_rp]
  1204.         add     edi, ecx
  1205.         sub     ecx, 512
  1206.         neg     ecx
  1207.         push    eax
  1208.         xor     eax, eax
  1209.         cld
  1210.         rep stosb
  1211.         pop     eax
  1212.  
  1213.         mov     [ebx+STREAM.out_count], 512
  1214.  
  1215. .add_buff:
  1216.         mov     ecx, [ebx+STREAM.out_rp]
  1217.         mov     [eax], ecx
  1218.  
  1219. if USE_SSE2_MIXER
  1220.         mov     edi, dword [ebx+STREAM.l_amp_f]
  1221.         mov     [eax+4], edi
  1222.         mov     edi, dword [ebx+STREAM.r_amp_f]
  1223.         mov     [eax+8], edi
  1224. else
  1225.         mov     edi, dword [ebx+STREAM.l_amp]
  1226.         mov     [eax+4], edi
  1227. end if
  1228.         add     [ebx+STREAM.out_rp], 512
  1229.         sub     [ebx+STREAM.out_count], 512
  1230.  
  1231.         add     eax, 12
  1232.         inc     edx
  1233. .next:
  1234.         mov     ebx, [ebx+STREAM.str_fd]
  1235.         jmp     @B
  1236. .done:
  1237.         mov     eax, edx
  1238.         ret
  1239.  
  1240. align 4
  1241. prepare_playlist:
  1242.  
  1243.         xor     edx, edx
  1244.         mov     [play_count], edx
  1245.         mov     esi, str.fd-FD_OFFSET
  1246.         mov     edi, [esi+STREAM.str_fd]
  1247. @@:
  1248.         cmp     edi, esi
  1249.         je      .done
  1250.  
  1251.         cmp     [edi+STREAM.magic], 'WAVE'
  1252.         jne     .next
  1253.  
  1254.         cmp     [edi+STREAM.size], STREAM.sizeof
  1255.         jne     .next
  1256.  
  1257.         cmp     [edi+STREAM.flags], SND_PLAY;
  1258.         jne     .next
  1259.  
  1260.         mov     [play_list+edx], edi
  1261.         inc     [play_count]
  1262.         add     edx, 4
  1263. .next:
  1264.         mov     edi, [edi+STREAM.str_fd]
  1265.         jmp     @B
  1266. .done:
  1267.         ret
  1268.  
  1269. align 4
  1270. proc set_handler stdcall, hsrv:dword, handler_proc:dword
  1271.            locals
  1272.              handler    dd ?
  1273.              io_code    dd ?
  1274.              input      dd ?
  1275.              inp_size   dd ?
  1276.              output     dd ?
  1277.              out_size   dd ?
  1278.              val        dd ?
  1279.            endl
  1280.  
  1281.         mov     eax, [hsrv]
  1282.         lea     ecx, [handler_proc]
  1283.         xor     ebx, ebx
  1284.  
  1285.         mov     [handler], eax
  1286.         mov     [io_code], DEV_CALLBACK
  1287.         mov     [input], ecx
  1288.         mov     [inp_size], 4
  1289.         mov     [output], ebx
  1290.         mov     [out_size], 0
  1291.  
  1292.         lea     eax, [handler]
  1293.         stdcall ServiceHandler, eax
  1294.         ret
  1295. endp
  1296.  
  1297. align 4
  1298. proc dev_play stdcall, hsrv:dword
  1299.            locals
  1300.              handle     dd ?
  1301.              io_code    dd ?
  1302.              input      dd ?
  1303.              inp_size   dd ?
  1304.              output     dd ?
  1305.              out_size   dd ?
  1306.              val        dd ?
  1307.            endl
  1308.  
  1309.         mov     eax, [hsrv]
  1310.         xor     ebx, ebx
  1311.  
  1312.         mov     [handle], eax
  1313.         mov     [io_code], DEV_PLAY
  1314.         mov     [input], ebx
  1315.         mov     [inp_size], ebx
  1316.         mov     [output], ebx
  1317.         mov     [out_size], ebx
  1318.  
  1319.         lea     eax, [handle]
  1320.         stdcall ServiceHandler, eax
  1321.         ret
  1322. endp
  1323.  
  1324. if 0
  1325. align 4
  1326. dword2str:
  1327.         mov     esi, hex_buff
  1328.         mov     ecx, -8
  1329. @@:
  1330.         rol     eax, 4
  1331.         mov     ebx, eax
  1332.         and     ebx, 0x0F
  1333.         mov     bl, [ebx+hexletters]
  1334.         mov     [8+esi+ecx], bl
  1335.         inc     ecx
  1336.         jnz     @B
  1337.         ret
  1338.  
  1339. hexletters   db '0123456789ABCDEF'
  1340. hex_buff     db 8 dup(0),13,10,0
  1341.  
  1342. end if
  1343.  
  1344. include 'mixer.asm'
  1345. include 'mix_mmx.inc'
  1346. include 'mix_sse2.inc'
  1347.  
  1348. ;if USE_SSE
  1349. ; include 'mix_sse.inc'
  1350. ;end if
  1351.  
  1352. align 16
  1353. resampler_params:
  1354.      ;r_size    r_dt   resampler_func
  1355.      dd 0,0,0                                  ; 0  PCM_ALL
  1356.      dd 16384,      0, copy_stream    ; 1  PCM_2_16_48
  1357.      dd  8192,      0, m16_stereo     ; 2  PCM_1_16_48
  1358.  
  1359.      dd 16384,  30109, resample_2     ; 3  PCM_2_16_44
  1360.      dd  8192,  30109, resample_1     ; 4  PCM_1_16_44
  1361.  
  1362.      dd 16384,  21846, resample_2     ; 5  PCM_2_16_32
  1363.      dd  8192,  21846, resample_1     ; 6  PCM_1_16_32
  1364.  
  1365.      dd 16384,  16384, resample_2     ; 7  PCM_2_16_24
  1366.      dd  8192,  16384, resample_1     ; 8  PCM_1_16_24
  1367.  
  1368.      dd  8192,  15052, resample_2     ; 9  PCM_2_16_22
  1369.      dd  4096,  15052, resample_1     ;10  PCM_1_16_22
  1370.  
  1371.      dd  8192,  10923, resample_2     ;11  PCM_2_16_16
  1372.      dd  4096,  10923, resample_1     ;12  PCM_1_16_16
  1373.  
  1374.      dd  8192,   8192, resample_2     ;13  PCM_2_16_12
  1375.      dd  4096,   8192, resample_1     ;14  PCM_1_16_12
  1376.  
  1377.      dd  4096,   7527, resample_2     ;15  PCM_2_16_11
  1378.      dd  2048,   7527, resample_1     ;16  PCM_1_16_11
  1379.  
  1380.      dd  4096,   5462, resample_2     ;17  PCM_2_16_8
  1381.      dd  2048,   5462, resample_1     ;18  PCM_1_16_8
  1382.  
  1383.      dd 16384,      0, s8_stereo      ;19  PCM_2_8_48
  1384.      dd  8192,      0, m8_stereo      ;20  PCM_1_8_48
  1385.  
  1386.      dd  8192,  30109, resample_28    ;21  PCM_2_8_44
  1387.      dd  4096,  30109, resample_18    ;22  PCM_1_8_44
  1388.  
  1389.      dd  8192,  21846, resample_28    ;23  PCM_2_8_32
  1390.      dd  4096,  21846, resample_18    ;24  PCM_1_8_32
  1391.  
  1392.      dd  8192,  16384, resample_28    ;25  PCM_2_8_24
  1393.      dd  4096,  16384, resample_18    ;26  PCM_1_8_24
  1394.  
  1395.      dd  4096,  15052, resample_28    ;27  PCM_2_8_22
  1396.      dd  2048,  15052, resample_18    ;28  PCM_1_8_22
  1397.  
  1398.      dd  4096,  10923, resample_28    ;29  PCM_2_8_16
  1399.      dd  2048,  10923, resample_18    ;30  PCM_1_8_16
  1400.  
  1401.      dd  4096,   8192, resample_28    ;31  PCM_2_8_12
  1402.      dd  2048,   8192, resample_18    ;32  PCM_1_8_12
  1403.  
  1404.      dd  2048,   7527, resample_28    ;33  PCM_2_8_11
  1405.      dd  1024,   7527, resample_18    ;34  PCM_1_8_11
  1406.  
  1407.      dd  2048,   5462, resample_28    ;35  PCM_2_8_8
  1408.      dd  1024,   5462, resample_18    ;36  PCM_1_8_8
  1409.  
  1410. m7            dw 0x8000,0x8000,0x8000,0x8000
  1411. mm80          dq 0x8080808080808080
  1412. mm_mask       dq 0xFF00FF00FF00FF00
  1413.  
  1414. vol_max       dd 0x00000000,0x00000000
  1415. vol_min       dd 0x0000D8F0,0x0000D8F0
  1416. pan_max       dd 0x00002710,0x00002710
  1417.  
  1418. ;stream_map    dd 0xFFFF       ; 16
  1419. version       dd (5 shl 16) or SOUND_VERSION
  1420.  
  1421. szInfinity    db 'INFINITY',0
  1422. szSound       db 'SOUND',0
  1423.  
  1424. if DEBUG
  1425. msgFail       db 'Sound service not loaded',13,10,0
  1426. msgPlay       db 'Play buffer',13,10,0
  1427. msgStop       db 'Stop',13,10,0
  1428. msgUser       db 'User callback',13,10,0
  1429. msgMem        db 'Not enough memory',13,10,0
  1430. msgDestroy    db 'Destroy sound buffer', 13,10,0
  1431. msgWaveout    db 'Play waveout', 13,10,0
  1432. msgSetVolume  db 'Set volume',13,10,0
  1433. end if
  1434.  
  1435. section '.data' data readable writable align 16
  1436.  
  1437. play_list     rd 16
  1438. mix_input     rd 16
  1439. play_count    rd 1
  1440. hSound        rd 1
  1441. eng_state     rd 1
  1442. mix_buff      rd 1
  1443. mix_buff_map  rd 1
  1444. str.fd        rd 1
  1445. str.bk        rd 1
  1446.  
  1447. mix_2_core    rd 1
  1448. mix_3_core    rd 1
  1449. mix_4_core    rd 1
  1450.