Subversion Repositories Kolibri OS

Rev

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

  1. ;
  2. ;   This file is part of the Infinity sound library.
  3. ;   (C) copyright Serge 2006
  4. ;   email: infinity_sound@mail.ru
  5. ;
  6. ;   This program is free software; you can redistribute it and/or modify
  7. ;   it under the terms of the GNU General Public License as published by
  8. ;   the Free Software Foundation; either version 2 of the License, or
  9. ;   (at your option) any later version.
  10. ;
  11. ;   This program is distributed in the hope that it will be useful,
  12. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ;   GNU General Public License for more details.
  15.  
  16. format MS COFF
  17.  
  18. include 'proc32.inc'
  19. include 'main.inc'
  20. include 'imports.inc'
  21.  
  22. DEBUG               equ 1
  23.  
  24. EVENT_NOTIFY        equ 0x00000200
  25.  
  26. OS_BASE               equ 0;  0x80400000
  27. new_app_base          equ 0x60400000;   0x01000000
  28. PROC_BASE             equ OS_BASE+0x0080000
  29.  
  30. public START
  31. public service_proc
  32. public version
  33.  
  34. SND_CREATE_BUFF     equ 2
  35. SND_PLAY            equ 3
  36. SND_STOP            equ 4
  37. SND_SETBUFF         equ 5
  38. SND_DESTROY_BUFF    equ 6
  39.  
  40. DEV_PLAY            equ 1
  41. DEV_STOP            equ 2
  42. DEV_CALLBACK        equ 3
  43.  
  44. struc IOCTL
  45. {  .handle           dd ?
  46.    .io_code          dd ?
  47.    .input            dd ?
  48.    .inp_size         dd ?
  49.    .output           dd ?
  50.    .out_size         dd ?
  51. }
  52.  
  53. virtual at 0
  54.   IOCTL IOCTL
  55. end virtual
  56.  
  57. section '.flat' code readable align 16
  58.  
  59. proc START stdcall, state:dword
  60.  
  61.            cmp [state], 1
  62.            jne .exit
  63.  
  64.            stdcall GetService, szSound
  65.            test eax, eax
  66.            jz .fail
  67.            mov [hSound], eax
  68.  
  69.            stdcall KernelAlloc, 16*512
  70.            test eax, eax
  71.            jz .out_of_mem
  72.            mov [mix_buff], eax
  73.  
  74.            mov edi, stream_list
  75.            mov ecx, 17
  76.            xor eax, eax
  77.            cld
  78.            rep stosd
  79.  
  80.            mov edi, stream
  81.            mov ecx, 4*STREAM_SIZE
  82.            rep stosd
  83.            mov [stream_count],0
  84.  
  85.            stdcall set_handler, [hSound], new_mix
  86.            stdcall RegService, szInfinity, service_proc
  87.            ret
  88. .fail:
  89.      if DEBUG
  90.            mov esi, msgFail
  91.            call SysMsgBoardStr
  92.      end if
  93. .exit:
  94.            xor eax, eax
  95.            ret
  96.  
  97. .out_of_mem:
  98.      if DEBUG
  99.            mov esi, msgMem
  100.            call SysMsgBoardStr
  101.      end if
  102.            xor eax, eax
  103.            ret
  104. endp
  105.  
  106. handle     equ  IOCTL.handle
  107. io_code    equ  IOCTL.io_code
  108. input      equ  IOCTL.input
  109. inp_size   equ  IOCTL.inp_size
  110. output     equ  IOCTL.output
  111. out_size   equ  IOCTL.out_size
  112.  
  113. align 4
  114. proc service_proc stdcall, ioctl:dword
  115.  
  116.            mov edi, [ioctl]
  117.            mov eax, [edi+io_code]
  118.  
  119.            cmp eax, SND_CREATE_BUFF
  120.            jne @F
  121.            mov ebx, [edi+input]
  122.            stdcall CreateBuffer,[ebx]
  123.            ret
  124. @@:
  125.            cmp eax, SND_PLAY
  126.            jne @F
  127.  
  128.            mov ebx, [edi+input]
  129.            stdcall play_buffer, [ebx]
  130.            ret
  131. @@:
  132.            cmp eax, SND_STOP
  133.            jne @F
  134.  
  135. ;       if DEBUG
  136. ;          mov esi, msgStop
  137. ;          call   [SysMsgBoardStr]
  138. ;       end if
  139.  
  140.            mov ebx, [edi+input]
  141.            stdcall stop_buffer, [ebx]
  142.            ret
  143. @@:
  144.            cmp eax, SND_SETBUFF
  145.            jne @F
  146.  
  147.            mov ebx, [edi+input]
  148.            mov eax, [ebx+4]
  149.            add eax, new_app_base
  150.            stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12]
  151.            ret
  152. @@:
  153.            cmp eax, SND_DESTROY_BUFF
  154.            jne @F
  155.  
  156.            mov ebx, [edi+input]
  157.            stdcall DestroyBuffer, [ebx]
  158.            ret
  159. @@:
  160.            xor eax, eax
  161.            ret
  162. endp
  163.  
  164. restore   handle
  165. restore   io_code
  166. restore   input
  167. restore   inp_size
  168. restore   output
  169. restore   out_size
  170.  
  171. TASK_COUNT    equ 0x0003004
  172. CURRENT_TASK  equ 0x0003000
  173.  
  174. align 8
  175. proc CreateBuffer stdcall, format:dword
  176.            locals
  177.              str dd ?
  178.            endl
  179.  
  180.            call alloc_stream
  181.            and eax, eax
  182.            jz .fail
  183.            mov [str], eax
  184.            mov edi, eax
  185.  
  186.            mov edx, [stream_count]
  187.            mov [stream_list+edx*4], eax
  188.            inc [stream_count]
  189.  
  190.            mov [edi+STREAM.magic], 'WAVE'
  191.            mov [edi+STREAM.size], STREAM_SIZE
  192.  
  193.            stdcall KernelAlloc, 180*1024
  194.  
  195.            mov edi, [str]
  196.            mov [edi+STREAM.base], eax
  197.            mov [edi+STREAM.seg_0], eax
  198.            mov [edi+STREAM.curr_seg], eax
  199.            mov [edi+STREAM.notify_off1], eax
  200.            add eax, 0x7FFF
  201.            mov [edi+STREAM.lim_0], eax
  202.            inc eax
  203.            mov [edi+STREAM.seg_1], eax
  204.            mov [edi+STREAM.notify_off2], eax
  205.            add eax, 0x7FFF
  206.            mov [edi+STREAM.limit], eax
  207.            mov [edi+STREAM.lim_1], eax
  208.            inc eax
  209.  
  210.            mov [edi+STREAM.work_buff], eax
  211.            mov [edi+STREAM.work_read], eax
  212.            mov [edi+STREAM.work_write], eax
  213.            mov [edi+STREAM.work_count], 0
  214.            add eax, 0x10000
  215.            mov [edi+STREAM.work_top], eax
  216.            add eax, 1024*32
  217.            mov [edi+STREAM.r_buff], eax
  218.  
  219.            mov ebx, [CURRENT_TASK]
  220.            shl ebx, 5
  221.            mov eax, [0x3000+ebx+4]
  222.  
  223.            mov [edi+STREAM.notify_task], eax
  224.  
  225.            mov eax, [format]
  226.            mov [edi+STREAM.format], eax
  227.            mov [edi+STREAM.flags], SND_STOP
  228.  
  229.            xor ebx, ebx
  230.            cmp eax, 19
  231.            jb @f
  232.            mov ebx, 0x80808080
  233. @@:
  234.            mov [edi+STREAM.r_silence], ebx
  235.  
  236.            shl eax, 4
  237.            mov ebx, [resampler_params+eax]
  238.            mov ecx, [resampler_params+eax+4]
  239.            mov edx, [resampler_params+eax+8]
  240.  
  241.            mov [edi+STREAM.r_size],ebx
  242.            mov [edi+STREAM.r_end], ecx
  243.            mov [edi+STREAM.r_dt],  edx
  244.  
  245.            mov ebx, [resampler_params+eax+12]
  246.            mov [edi+STREAM.resample], ebx
  247.  
  248.            mov edi, [edi+STREAM.base]
  249.            mov ecx, 180*1024/4
  250.            xor eax, eax
  251.            rep stosd
  252.  
  253.            mov eax, [str]
  254.            ret
  255. .fail:
  256.            xor eax, eax
  257.            ret
  258. endp
  259.  
  260. align 4
  261. pid_to_slot:
  262.  
  263.            push   ebx
  264.            push   ecx
  265.            mov    ebx,[TASK_COUNT]
  266.            shl    ebx,5
  267.            mov    ecx,2*32
  268. .loop:
  269.            cmp    byte [CURRENT_TASK+ecx+0xa],9
  270.            jz     .endloop              ;skip empty slots
  271.            cmp    [CURRENT_TASK+ecx+0x4],eax ;check PID
  272.            jz     .pid_found
  273. .endloop:
  274.            add    ecx,32
  275.            cmp    ecx,ebx
  276.            jle    .loop
  277.            pop    ecx
  278.            pop    ebx
  279.            xor    eax,eax
  280.            ret
  281.  
  282. .pid_found:
  283.            shr    ecx,5
  284.            mov    eax,ecx
  285.            pop    ecx
  286.            pop    ebx
  287.            ret
  288.  
  289. align 4
  290. proc DestroyBuffer stdcall, str:dword
  291.  
  292.            mov esi, [str]
  293.  
  294.            cmp [esi+STREAM.magic], 'WAVE'
  295.            jne .fail
  296.  
  297.            cmp [esi+STREAM.size], STREAM_SIZE
  298.            jne .fail
  299.  
  300.            stdcall KernelFree, [esi+STREAM.base]
  301.  
  302.            mov eax, [str]
  303.            call free_stream
  304.  
  305.            mov edi, [str]
  306.            mov ecx, STREAM_SIZE/4
  307.            xor eax, eax
  308.            cld
  309.            rep stosd
  310.  
  311.            mov eax, [str]
  312.            mov esi, stream_list
  313.            mov ecx, 16
  314. @@:
  315.            cmp [esi], eax
  316.            je .remove
  317.            add esi, 4
  318.            dec ecx
  319.            jnz @B
  320.            xor eax, eax
  321.            inc eax
  322.            ret
  323. .remove:
  324.            mov edi, esi
  325.            add esi, 4
  326.            cld
  327.            rep movsd
  328.            dec [stream_count]
  329.            xor eax, eax
  330.            inc eax
  331.            ret
  332. .fail:
  333.            xor eax, eax
  334.            ret
  335. endp
  336.  
  337. align 4
  338. proc play_buffer stdcall, str:dword
  339.  
  340.            mov ebx, [str]
  341.  
  342.            cmp [ebx+STREAM.magic], 'WAVE'
  343.            jne .fail
  344.  
  345.            cmp [ebx+STREAM.size], STREAM_SIZE
  346.            jne .fail
  347.  
  348.            mov [ebx+STREAM.flags], SND_PLAY
  349.  
  350.            mov eax,[ebx+STREAM.work_buff]
  351.            mov [ebx+STREAM.work_read], eax
  352.            mov [ebx+STREAM.work_write], eax
  353.            mov [ebx+STREAM.work_count], 0
  354.  
  355.            mov eax, [ebx+STREAM.seg_0]
  356.            mov [ebx+STREAM.curr_seg], eax
  357.  
  358.            mov esi, [ebx+STREAM.curr_seg]
  359.            mov edi, [ebx+STREAM.work_write]
  360.            mov edx, [ebx+STREAM.r_buff]
  361.  
  362.            mov ecx, 32
  363.            mov eax, [ebx+STREAM.r_silence]
  364. @@:
  365.            mov [edx], eax
  366.            add edx, 4
  367.            dec ecx
  368.            jnz @B
  369.  
  370.            mov edx, [ebx+STREAM.r_buff]
  371.  
  372.            stdcall [ebx+STREAM.resample], edi, esi, edx,\
  373.            [ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end]
  374.  
  375.            mov ebx, [str]
  376.  
  377.            add [ebx+STREAM.work_count], eax;
  378.            add [ebx+STREAM.work_write], eax;
  379.  
  380.            mov eax, [ebx+STREAM.r_size]
  381.            add [ebx+STREAM.curr_seg], eax
  382.  
  383. ;       if DEBUG
  384. ;          mov esi, msgPlay
  385. ;          call   [SysMsgBoardStr]
  386. ;       end if
  387.  
  388.            stdcall  dev_play, [hSound]
  389.            xor eax, eax
  390.            inc eax
  391.            ret
  392. .fail:
  393.            xor eax, eax
  394.            ret
  395. endp
  396.  
  397. align 4
  398. proc stop_buffer stdcall, str:dword
  399.  
  400.            mov edi, [str]
  401.  
  402.            cmp [edi+STREAM.magic], 'WAVE'
  403.            jne .fail
  404.  
  405.            cmp [edi+STREAM.size], STREAM_SIZE
  406.            jne .fail
  407.  
  408.            mov [edi+STREAM.flags], SND_STOP
  409.  
  410. ;           stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
  411.  
  412.            xor eax, eax
  413.            inc eax
  414.            ret
  415. .fail:
  416.            xor eax, eax
  417.            ret
  418. endp
  419.  
  420. align 4
  421. proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
  422.  
  423.            mov edx, [str]
  424.            test edx, edx
  425.            jz .fail
  426.  
  427.            cmp [edx+STREAM.magic], 'WAVE'
  428.            jne .fail
  429.  
  430.            cmp [edx+STREAM.size], STREAM_SIZE
  431.            jne .fail
  432.  
  433.            mov esi,[src]
  434.            test esi, esi
  435.            jz .fail
  436.  
  437.            cmp esi, new_app_base
  438.            jb .fail
  439.  
  440.            mov ecx, [size]
  441.            test ecx, ecx
  442.            jz .fail
  443.  
  444.            mov eax, [edx+STREAM.base]
  445.            add eax, [offs]
  446.  
  447.            cmp eax, [edx+STREAM.base]
  448.            jb .fail
  449.  
  450.            mov edi, eax
  451.            add eax, ecx
  452.            sub eax, 1
  453.  
  454.            cmp eax, [edx+STREAM.limit]
  455.            ja .fail
  456.  
  457.            shr ecx, 2
  458.            cld
  459.            rep movsd
  460.  
  461.            xor eax, eax
  462.            inc eax
  463.            ret
  464. .fail:
  465.            xor eax, eax
  466.            ret
  467. endp
  468.  
  469. align 4
  470. proc alloc_stream
  471.  
  472.            mov esi, stream_map
  473.  
  474.            pushf
  475.            cli
  476.  
  477.            bsf eax, [esi]
  478.            jnz .find
  479.            popf
  480.            xor eax, eax
  481.            ret
  482. .find:
  483.            btr [esi], eax
  484.            popf
  485.            mov ebx, STREAM_SIZE
  486.            mul ebx
  487.            add eax, stream
  488.            ret
  489. endp
  490.  
  491. align 4
  492. proc free_stream
  493.            sub eax, stream
  494.            mov ebx, STREAM_SIZE
  495.            xor edx, edx
  496.            div ebx
  497.  
  498.            and edx, edx
  499.            jnz .err
  500.  
  501.            bts [stream_map], eax
  502.            ret
  503. .err:
  504.            xor eax, eax
  505.            ret
  506. endp
  507.  
  508. if 0
  509. align 4
  510. proc check_stream
  511.  
  512.            xor edx, edx
  513.            mov ecx, [play_count]
  514. .l1:
  515.            mov esi, [play_list+edx]
  516.  
  517.            mov eax, [esi+STR.curr_seg]
  518.            cmp eax, [esi+STR.lim_0]
  519.            jb .next
  520.  
  521.            mov eax, [esi+STREAM.seg_0]
  522.            mov ecx, [esi+STREAM.lim_0]
  523.            xchg eax, [ebx+STREAM.seg_1]
  524.            xchg ecx, [ebx+STREAM.lim_1]
  525.            mov [esi+STREAM.seg_0], eax
  526.            mov [esi+STREAM.lim_0], ecx
  527.            mov [esi+STR.curr_seg], eax
  528. .next:
  529.            add edx, 4
  530.            loop .l1
  531.            ret
  532. endp
  533. end if
  534.  
  535. align 4
  536. proc prepare_playlist
  537.  
  538. .restart:
  539.            xor ebx, ebx
  540.            xor edx, edx
  541.            mov [play_count], 0
  542.            mov ecx, [stream_count]
  543.            jcxz .exit
  544. .l1:
  545.            mov esi, [stream_list+ebx]
  546.            test esi, esi
  547.            jz .next
  548.  
  549.            cmp [esi+STREAM.magic], 'WAVE'
  550.            jne .next
  551.  
  552.            cmp [esi+STREAM.size], STREAM_SIZE
  553.            jne .next
  554.  
  555.            mov eax,[esi+STREAM.notify_task]
  556.            cmp eax, -1
  557.            je .fail
  558.  
  559.            call pid_to_slot
  560.            test eax, eax
  561.            jz .fail
  562.  
  563.            cmp [esi+STREAM.flags], SND_PLAY;
  564.            jne .next
  565.            cmp [esi+STREAM.work_count], 16384
  566.            jb .next
  567.  
  568.            mov [play_list+edx], esi
  569.            inc [play_count]
  570.            add edx, 4
  571. .next:
  572.            add ebx, 4
  573.            loop .l1
  574. .exit:
  575.            ret
  576. .fail:
  577.            stdcall DestroyBuffer, esi
  578.            jmp .restart
  579. endp
  580.  
  581. align 4
  582. proc prepare_updatelist
  583.  
  584.            xor ebx, ebx
  585.            xor edx, edx
  586.            mov [play_count], 0
  587.            mov ecx, [stream_count]
  588.            jcxz .exit
  589. .l1:
  590.            mov eax, [stream_list+ebx]
  591.            test eax, eax
  592.            jz .next
  593.            cmp [eax+STREAM.flags], SND_PLAY
  594.            jne .next
  595.  
  596.            mov [play_list+edx], eax
  597.            inc [play_count]
  598.            add edx, 4
  599. .next:
  600.            add ebx, 4
  601.            loop .l1
  602. .exit:
  603.            ret
  604. endp
  605.  
  606. align 4
  607. proc set_handler stdcall, hsrv:dword, handler_proc:dword
  608.            locals
  609.              handler    dd ?
  610.              io_code    dd ?
  611.              input      dd ?
  612.              inp_size   dd ?
  613.              output     dd ?
  614.              out_size   dd ?
  615.              val        dd ?
  616.            endl
  617.  
  618.            mov eax, [hsrv]
  619.            lea ecx, [handler_proc]
  620.            xor ebx, ebx
  621.  
  622.            mov [handler], eax
  623.            mov [io_code], DEV_CALLBACK
  624.            mov [input], ecx
  625.            mov [inp_size], 4
  626.            mov [output], ebx
  627.            mov [out_size], 0
  628.  
  629.            lea eax, [handler]
  630.            stdcall ServiceHandler, eax
  631.            ret
  632. endp
  633.  
  634. align 4
  635. proc dev_play stdcall, hsrv:dword
  636.            locals
  637.              handle     dd ?
  638.              io_code    dd ?
  639.              input      dd ?
  640.              inp_size   dd ?
  641.              output     dd ?
  642.              out_size   dd ?
  643.              val        dd ?
  644.            endl
  645.  
  646.            mov eax, [hsrv]
  647.            xor ebx, ebx
  648.  
  649.            mov [handle], eax
  650.            mov [io_code], DEV_PLAY
  651.            mov [input], ebx
  652.            mov [inp_size], ebx
  653.            mov [output], ebx
  654.            mov [out_size], ebx
  655.  
  656.            lea eax, [handle]
  657.            stdcall ServiceHandler, eax
  658.            ret
  659. endp
  660.  
  661. include 'mixer.asm'
  662.  
  663. align 16
  664. resampler_params:
  665.      ;r_size    r_end   r_dt   resampler_func
  666.      dd 0,0,0,0                                  ; 0  PCM_ALL
  667.      dd 16384,          0,     0, copy_stream    ; 1  PCM_2_16_48
  668.      dd 16384,          0,     0, m16_stereo     ; 2  PCM_1_16_48
  669.  
  670.      dd 16384, 0x08000000, 30109, resample_2     ; 3  PCM_2_16_44
  671.      dd  8192, 0x08000000, 30109, resample_1     ; 4  PCM_1_16_44
  672.  
  673.      dd 16384, 0x08000000, 21846, resample_2     ; 5  PCM_2_16_32
  674.      dd  8192, 0x08000000, 21846, resample_1     ; 6  PCM_1_16_32
  675.  
  676.      dd 16384, 0x08000000, 16384, resample_2     ; 7  PCM_2_16_24
  677.      dd  8192, 0x08000000, 16384, resample_1     ; 8  PCM_1_16_24
  678.  
  679.      dd  8192, 0x04000000, 15052, resample_2     ; 9  PCM_2_16_22
  680.      dd  4096, 0x04000000, 15052, resample_1     ;10  PCM_1_16_22
  681.  
  682.      dd  8192, 0x04000000, 10923, resample_2     ;11  PCM_2_16_16
  683.      dd  4096, 0x04000000, 10923, resample_1     ;12  PCM_1_16_16
  684.  
  685.      dd  8192, 0x04000000,  8192, resample_2     ;13  PCM_2_16_12
  686.      dd  4096, 0x04000000,  8192, resample_1     ;14  PCM_1_16_12
  687.  
  688.      dd  4096, 0x02000000,  7527, resample_2     ;15  PCM_2_16_11
  689.      dd  2048, 0x02000000,  7527, resample_1     ;16  PCM_1_16_11
  690.  
  691.      dd  4096, 0x02000000,  5462, resample_2     ;17  PCM_2_16_8
  692.      dd  2048, 0x02000000,  5462, resample_1     ;18  PCM_1_16_8
  693.  
  694.      dd 16384,          0,     0, s8_stereo      ;19  PCM_2_8_48
  695.      dd  8192,          0,     0, m8_stereo      ;20  PCM_1_8_48
  696.  
  697.      dd  8192, 0x08000000, 30109, resample_28    ;21  PCM_2_8_44
  698.      dd  4096, 0x08000000, 30109, resample_18    ;22  PCM_1_8_44
  699.  
  700.      dd  8192, 0x08000000, 21846, resample_28    ;23  PCM_2_8_32
  701.      dd  4096, 0x08000000, 21846, resample_18    ;24  PCM_1_8_32
  702.  
  703.      dd  8192, 0x08000000, 16384, resample_28    ;25  PCM_2_8_24
  704.      dd  4096, 0x08000000, 16384, resample_18    ;26  PCM_1_8_24
  705.  
  706.      dd  4096, 0x04000000, 15052, resample_28    ;27  PCM_2_8_22
  707.      dd  2048, 0x04000000, 15052, resample_18    ;28  PCM_1_8_22
  708.  
  709.      dd  4096, 0x04000000, 10923, resample_28    ;29  PCM_2_8_16
  710.      dd  2048, 0x04000000, 10923, resample_18    ;30  PCM_1_8_16
  711.  
  712.      dd  4096, 0x04000000,  8192, resample_28    ;31  PCM_2_8_12
  713.      dd  2048, 0x04000000,  8192, resample_18    ;32  PCM_1_8_12
  714.  
  715.      dd  2048, 0x02000000,  7527, resample_28    ;33  PCM_2_8_11
  716.      dd  1024, 0x02000000,  7527, resample_18    ;34  PCM_1_8_11
  717.  
  718.      dd  2048, 0x02000000,  5462, resample_28    ;35  PCM_2_8_8
  719.      dd  1024, 0x02000000,  5462, resample_18    ;36  PCM_1_8_8
  720.  
  721. m7            dw 0x8000,0x8000,0x8000,0x8000
  722. mm80          dq 0x8080808080808080
  723. mm_mask       dq 0xFF00FF00FF00FF00
  724.  
  725. stream_map    dd 0xFFFF       ; 16
  726. version       dd 0x00020002
  727.  
  728. szInfinity    db 'INFINITY',0
  729. szSound       db 'SOUND',0
  730.  
  731. if DEBUG
  732. msgFail       db 'Sound service not loaded',13,10,0
  733. msgPlay       db 'Play buffer',13,10,0
  734. msgStop       db 'Stop',13,10,0
  735. msgUser       db 'User callback',13,10,0
  736. msgMem        db 'Not enough memory',13,10,0
  737. end if
  738.  
  739. section '.data' data readable writable align 16
  740.  
  741. stream        rb STREAM_SIZE*16
  742.  
  743. play_list     rd 16
  744. mix_input     rd 16
  745.  
  746. stream_list   rd 17
  747. play_count    rd 1
  748. stream_count  rd 1
  749. hSound        rd 1
  750. mix_buff      rd 1
  751. mix_buff_map  rd 1
  752.  
  753.