Subversion Repositories Kolibri OS

Rev

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