Subversion Repositories Kolibri OS

Rev

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