Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. ;   (C) copyright Serge 2006
  9. ;   email: infinity_sound@mail.ru
  10.  
  11.  
  12. align 4
  13.  
  14. mix_list rd 32*3
  15.  
  16. align 4
  17. proc new_mix stdcall, output:dword
  18.            locals
  19.              main_count   rd 1
  20.              fpu_state    rb 528   ;512+16
  21.            endl
  22.  
  23.            mov [main_count], 32
  24.            call prepare_playlist
  25.            cmp [play_count], 0
  26.            je .clear
  27.  
  28.            lea eax, [fpu_state+16]
  29.            and eax, -16             ;must be 16b aligned
  30.            call FpuSave
  31.  
  32.            call update_stream
  33. .mix:
  34.            lea eax, [mix_list]
  35.            call do_mix_list
  36.            test eax, eax
  37.            je .done
  38.  
  39.            lea ebx, [mix_list]
  40.            stdcall mix_all, [output], ebx, eax
  41. @@:
  42.            add [output], 512
  43.            dec [main_count]
  44.            jnz .mix
  45. .exit:
  46.            lea eax, [fpu_state+16]
  47.            and eax, -16
  48.            call FpuRestore
  49.            ret
  50. .copy:
  51.            lea eax, [mix_list]
  52.            stdcall copy_mem, [output], [eax]
  53.            jmp @B
  54. .done:
  55.            mov ecx, [main_count]
  56.            shl ecx, 7     ;ecx*= 512/4
  57.  
  58.            mov edi, [output]
  59.            xor eax, eax
  60.            cld
  61.            rep stosd
  62.            jmp .exit
  63. .clear:
  64.            mov edi, [output]
  65.            mov ecx, 4096
  66.            xor eax, eax
  67.            cld
  68.            rep stosd
  69.            ret
  70. endp
  71.  
  72. align 4
  73. proc update_stream
  74.            locals
  75.              stream_index  dd ?
  76.              event         rd 6
  77.            endl
  78.  
  79.            mov [stream_index], 0
  80. .l1:
  81.            mov edx, [stream_index]
  82.            mov esi, [play_list+edx*4]
  83.  
  84.            mov eax, [esi+STREAM.out_rp]
  85.            cmp eax, [esi+STREAM.out_top]
  86.            jb @f
  87.            sub eax, 64*1024
  88. @@:
  89.            mov [esi+STREAM.out_rp], eax
  90.  
  91.            cmp [esi+STREAM.out_count], 16384
  92.            ja .skip
  93.  
  94.            test [esi+STREAM.format], PCM_RING
  95.            jnz .ring
  96.  
  97.            stdcall refill, esi
  98. .skip:
  99.            inc [stream_index]
  100.            dec [play_count]
  101.            jnz .l1
  102.            ret
  103. .ring:
  104.            stdcall refill_ring, esi
  105.            jmp .skip
  106. endp
  107.  
  108. align 4
  109. proc refill stdcall, str:dword
  110.            locals
  111.              r_size    rd 1
  112.            endl
  113.  
  114.            mov ebx, [str]
  115.            mov edi, [ebx+STREAM.out_wp]
  116.            cmp edi, [ebx+STREAM.out_top]
  117.            jb @F
  118.            sub edi, 0x10000
  119.            mov [ebx+STREAM.out_wp], edi
  120. @@:
  121.            mov eax, [ebx+STREAM.in_count]
  122.            test eax, eax
  123.            jz .done
  124.  
  125.            mov ecx, [ebx+STREAM.r_size]
  126.            cmp eax, ecx
  127.            jle @F
  128.  
  129.            mov eax, ecx
  130. @@:
  131.            mov ecx, eax
  132.            cmp word [ebx+STREAM.format], PCM_1_16_8
  133.            ja @F
  134.  
  135.            shr eax, 1                   ;two channles
  136. @@:
  137.            test [ebx+STREAM.format], 1  ;even formats mono
  138.            jz @F
  139.  
  140.            shr eax, 1                   ;eax= samples
  141. @@:
  142.            shl eax, 15    ;eax*=32768 =r_end
  143.  
  144.            mov [r_size], ecx
  145.  
  146.            mov esi, [ebx+STREAM.in_rp]
  147.            mov edi, [ebx+STREAM.out_wp]
  148.  
  149.            stdcall [ebx+STREAM.resample], edi, esi, \
  150.            [ebx+STREAM.r_dt], ecx, eax
  151.  
  152.            mov ebx, [str]
  153.  
  154.            add [ebx+STREAM.out_count], eax;
  155.            add [ebx+STREAM.out_wp], eax;
  156.  
  157.            mov eax, [ebx+STREAM.in_rp]
  158.            mov ecx, [r_size]
  159.            add eax, ecx
  160.            add [ebx+STREAM.in_free], ecx
  161.            sub [ebx+STREAM.in_count], ecx
  162.  
  163.            cmp eax, [ebx+STREAM.in_top]
  164.            jb @f
  165.  
  166.            sub eax, [ebx+STREAM.in_size]
  167. @@:
  168.            mov [ebx+STREAM.in_rp], eax
  169.  
  170. .done:
  171.            mov eax, [ebx+STREAM.notify_event]
  172.            test eax, eax
  173.            jz .exit
  174.  
  175.            mov ebx, [ebx+STREAM.notify_id]
  176.            mov ecx, EVENT_WATCHED
  177.            xor edx, edx
  178.            call RaiseEvent   ;eax, ebx, ecx, edx
  179. .exit:
  180.            ret
  181. endp
  182.  
  183. align 4
  184. proc refill_ring stdcall, str:dword
  185.            locals
  186.              event     rd 6
  187.            endl
  188.  
  189.            mov ebx, [str]
  190.            mov edi, [ebx+STREAM.out_wp]
  191.            cmp edi, [ebx+STREAM.out_top]
  192.            jb @F
  193.            sub edi, 0x10000
  194.            mov [ebx+STREAM.out_wp], edi
  195. @@:
  196.            mov ecx, [ebx+STREAM.r_size]
  197.            mov eax, ecx
  198.            cmp word [ebx+STREAM.format], PCM_1_16_8
  199.            ja @F
  200.  
  201.            shr eax, 1                   ;two channles
  202. @@:
  203.            test [ebx+STREAM.format], 1  ;even formats mono
  204.            jz @F
  205.  
  206.            shr eax, 1                   ;eax= samples
  207. @@:
  208.            shl eax, 15    ;eax*=32768 =r_end
  209.  
  210.            mov esi, [ebx+STREAM.in_rp]
  211.            mov edi, [ebx+STREAM.out_wp]
  212.  
  213.            stdcall [ebx+STREAM.resample], edi, esi, \
  214.            [ebx+STREAM.r_dt], ecx, eax
  215.  
  216.            mov ebx, [str]
  217.  
  218.            add [ebx+STREAM.out_count], eax;
  219.            add [ebx+STREAM.out_wp], eax;
  220.  
  221.            mov eax, [ebx+STREAM.in_rp]
  222.            mov ecx, [ebx+STREAM.r_size]
  223.            add eax, ecx
  224.            add [ebx+STREAM.in_free], ecx
  225.            sub [ebx+STREAM.in_count], ecx
  226.  
  227.            cmp eax, [ebx+STREAM.in_top]
  228.            jb @f
  229.  
  230.            sub eax, [ebx+STREAM.in_size]
  231. @@:
  232.            mov [ebx+STREAM.in_rp], eax
  233.  
  234.            sub eax, [ebx+STREAM.in_base]
  235.            sub eax, 128
  236.            lea edx, [event]
  237.  
  238.            mov dword [edx], RT_INP_EMPTY
  239.            mov dword [edx+4], 0
  240.            mov dword [edx+8], ebx
  241.            mov dword [edx+12], eax
  242.  
  243.            mov eax, [ebx+STREAM.notify_event]
  244.            test eax, eax
  245.            jz .exit
  246.  
  247.            mov ebx, [ebx+STREAM.notify_id]
  248.            xor ecx, ecx
  249.            call RaiseEvent   ;eax, ebx, ecx, edx
  250. .exit:
  251.            ret
  252. endp
  253.  
  254. if USE_SSE2_MIXER
  255.  
  256. align 4
  257. proc mix_all stdcall, dest:dword, list:dword, count:dword
  258.  
  259.            mov edi, [dest]
  260.            mov ebx, 32
  261. .mix:
  262.            mov edx, [list]
  263.            mov ecx, [count]
  264.  
  265.            mov eax, [edx]
  266.  
  267.            movdqa xmm1, [eax]
  268.            movss xmm2, [edx+4]
  269.            movss xmm3, [edx+8]
  270.  
  271.            punpcklwd xmm0, xmm1
  272.            punpckhwd xmm1, xmm1
  273.  
  274.            shufps xmm2, xmm3, 0
  275.            shufps xmm2, xmm2, 0x88
  276.  
  277.            psrad xmm0, 16
  278.            psrad xmm1, 16
  279.            cvtdq2ps xmm0, xmm0     ;time to use all power
  280.            cvtdq2ps xmm1, xmm1     ;of the dark side
  281.            mulps xmm0, xmm2
  282.            mulps xmm1, xmm2
  283.  
  284. .mix_loop:
  285.            add dword [edx], 16
  286.            add edx, 12
  287.            dec ecx
  288.            jz @F
  289.  
  290.            mov eax, [edx]
  291.  
  292.            movdqa xmm3, [eax]
  293.            movss xmm4, [edx+4]
  294.            movss xmm5, [edx+8]
  295.  
  296.            punpcklwd xmm2, xmm3
  297.            punpckhwd xmm3, xmm3
  298.  
  299.            shufps xmm4, xmm5, 0
  300.            shufps xmm4, xmm4, 0x88
  301.  
  302.            psrad xmm2, 16
  303.            psrad xmm3, 16
  304.  
  305.            cvtdq2ps xmm2, xmm2
  306.            cvtdq2ps xmm3, xmm3
  307.  
  308.            mulps xmm2, xmm4
  309.            mulps xmm3, xmm4
  310.            addps xmm0, xmm2
  311.            addps xmm1, xmm3
  312.  
  313.            jmp .mix_loop
  314. @@:
  315.            cvtps2dq xmm0, xmm0
  316.            cvtps2dq xmm1, xmm1
  317.            packssdw xmm0, xmm0
  318.            packssdw xmm1, xmm1
  319.            punpcklqdq xmm0, xmm1
  320.            movntdq [edi], xmm0
  321.  
  322.            add edi, 16
  323.            dec ebx
  324.            jnz .mix
  325.  
  326.            ret
  327. endp
  328.  
  329. else                                    ; fixed point mmx version
  330.  
  331. align 4
  332. proc mix_all stdcall, dest:dword, list:dword, count:dword
  333.  
  334.            mov edi, [dest]
  335.            mov ebx, 64
  336. .mix:
  337.            mov edx, [list]
  338.            mov ecx, [count]
  339.  
  340.            mov eax, [edx]
  341.  
  342.            movq mm0, [eax]
  343.  
  344.            movd mm1, [edx+4]
  345.            punpckldq mm1,mm1
  346.            pmulhw mm0, mm1
  347.            psllw  mm0, 1
  348.  
  349. .mix_loop:
  350.            add dword [edx], 8
  351.            add edx, 12
  352.            dec ecx
  353.            jz @F
  354.  
  355.            mov eax, [edx]
  356.            movq mm1, [eax]
  357.            movd mm2, [edx+4]
  358.            punpckldq mm2,mm2
  359.            pmulhw mm1, mm2
  360.            psllw  mm1, 1
  361.            paddsw mm0, mm1
  362.            jmp .mix_loop
  363. @@:
  364.            movq [edi], mm0
  365.            add edi, 8
  366.            dec ebx
  367.            jnz .mix
  368.  
  369.            ret
  370. endp
  371.  
  372. end if
  373.  
  374.  
  375. align 4
  376. proc resample_1 stdcall, dest:dword,src:dword,\
  377.                        r_dt:dword, r_size:dword,r_end:dword
  378.  
  379. ; dest equ esp+8
  380. ; src  equ esp+12
  381. ; r_dt equ esp+16
  382. ; r_size equ esp+20
  383. ; r_end equ esp+24
  384.  
  385.            mov edi, [dest]
  386.            mov edx, [src]
  387.            sub edx, 32*2
  388.            mov eax, 16
  389.  
  390. align 4
  391. .l1:
  392.            mov ecx, eax
  393.            mov esi, eax
  394.            and ecx, 0x7FFF
  395.            shr esi, 15
  396.            lea esi, [edx+esi*2]
  397.  
  398.            movsx ebp, word [esi]
  399.            movsx esi, word [esi+2]
  400.            mov ebx, 32768
  401.            imul esi, ecx
  402.            sub ebx, ecx
  403.            imul ebx, ebp
  404.            lea ecx, [ebx+esi+16384]
  405.            sar ecx, 15
  406.            cmp ecx, 32767         ; 00007fffH
  407.            jle @f
  408.            mov ecx, 32767         ; 00007fffH
  409.            jmp .write
  410. @@:
  411.            cmp ecx, -32768        ; ffff8000H
  412.            jge .write
  413.            mov ecx, -32768        ; ffff8000H
  414. .write:
  415.            mov ebx, ecx
  416.            shl ebx, 16
  417.            mov bx, cx
  418.            mov [edi], ebx
  419.            add edi, 4
  420.  
  421.            add eax, [esp+16]
  422.            cmp eax, [esp+24]
  423.            jb .l1
  424.  
  425.            mov ebp, esp
  426.  
  427.            sub edi, [dest]
  428.            mov eax, edi
  429.            ret
  430. endp
  431.  
  432. align 4
  433. proc resample_18 stdcall, dest:dword,src:dword,\
  434.                        r_dt:dword, r_size:dword,r_end:dword
  435.  
  436.  
  437.            mov edi, [dest]
  438.            mov edx, [src]
  439.            sub edx, 32
  440.  
  441.            mov esi, 16
  442.  
  443. align 4
  444. .l1:
  445.            mov ecx, esi
  446.            mov eax, esi
  447.            and ecx, 0x7FFF
  448.            shr eax, 15
  449.            lea eax, [edx+eax]
  450.  
  451.            mov bx, word [eax]
  452.            sub bh, 0x80
  453.            sub bl, 0x80
  454.            movsx eax, bh
  455.            shl eax,8
  456.            movsx ebp, bl
  457.            shl ebp,8
  458.            mov ebx, 32768
  459.            imul eax, ecx
  460.            sub ebx, ecx
  461.            imul ebx, ebp
  462.            lea ecx, [ebx+eax+16384]
  463.            sar ecx, 15
  464.            cmp ecx, 32767         ; 00007fffH
  465.            jle @f
  466.            mov ecx, 32767         ; 00007fffH
  467.            jmp .write
  468. @@:
  469.            cmp ecx, -32768        ; ffff8000H
  470.            jge .write
  471.            mov ecx, -32768        ; ffff8000H
  472. .write:
  473.            mov ebx, ecx
  474.            shl ebx, 16
  475.            mov bx, cx
  476.            mov [edi], ebx
  477.            add edi, 4
  478.  
  479.            add esi, [esp+16]
  480.            cmp esi, [esp+24]
  481.            jb .l1
  482.  
  483.            mov ebp, esp
  484.            sub edi, [dest]
  485.            mov eax, edi
  486.            ret
  487. endp
  488.  
  489. align 4
  490. proc copy_stream stdcall, dest:dword,src:dword,\
  491.                        r_dt:dword, r_size:dword,r_end:dword
  492.  
  493.            mov ecx, [r_size]
  494.            mov eax, ecx
  495.            shr ecx, 2
  496.            mov esi, [src]
  497.            mov edi, [dest]
  498.            cld
  499.            rep movsd
  500.            ret
  501. endp
  502.  
  503. align 4
  504. proc resample_2 stdcall, dest:dword,src:dword,\
  505.                        r_dt:dword, r_size:dword,r_end:dword
  506.  
  507.            mov edx, [src]
  508.            sub edx, 32*4
  509.            mov edi, [dest]
  510.            mov ebx, [r_dt]
  511.            mov eax, 16
  512.            emms
  513.  
  514. align 4
  515. .l1:
  516.            mov ecx, eax
  517.            mov esi, eax
  518.            and ecx, 0x7FFF
  519.            shr esi, 15
  520.            lea esi, [edx+esi*4]
  521.  
  522.            movq mm0, [esi]
  523.            movq mm1, mm0
  524.  
  525.            movd mm2, ecx
  526.            punpcklwd mm2, mm2
  527.            movq mm3, qword [m7]    ;0x8000
  528.  
  529.            psubw mm3, mm2 ;        ;0x8000 - iconst
  530.            punpckldq mm3, mm2
  531.  
  532.            pmulhw mm0, mm3
  533.            pmullw mm1, mm3
  534.  
  535.            movq mm4, mm1
  536.            punpcklwd mm1, mm0
  537.            punpckhwd mm4, mm0
  538.            paddd mm1, mm4
  539.            psrad  mm1, 15
  540.            packssdw mm1, mm1
  541.            movd [edi], mm1
  542.            add edi, 4
  543.  
  544.            add eax, ebx
  545.            cmp eax, [r_end]
  546.            jb .l1
  547.            emms
  548.  
  549.            sub edi, [dest]
  550.            mov eax, edi
  551.            ret
  552. endp
  553.  
  554. align 4
  555. proc resample_28 stdcall, dest:dword,src:dword,\
  556.                        r_dt:dword, r_size:dword,r_end:dword
  557.  
  558.            mov edx, [src]
  559.            sub edx, 32*2
  560.            mov edi, [dest]
  561.            mov ebx, [r_dt]
  562.            mov eax, 16
  563.            emms
  564.            movq mm7,[mm80]
  565.            movq mm6,[mm_mask]
  566.  
  567. align 4
  568. .l1:
  569.            mov ecx, eax
  570.            mov esi, eax
  571.            and ecx, 0x7FFF
  572.            shr esi, 15
  573.            lea esi, [edx+esi*2]
  574.  
  575.            movq mm0, [esi]
  576.            psubb mm0,mm7
  577.            punpcklbw mm0,mm0
  578.            pand mm0,mm6
  579.  
  580.            movq mm1, mm0
  581.  
  582.            movd mm2, ecx
  583.            punpcklwd mm2, mm2
  584.            movq mm3, qword [m7] ;                  // 0x8000
  585.  
  586.            psubw mm3, mm2       ;         // 0x8000 - iconst
  587.            punpckldq mm3, mm2
  588.  
  589.            pmulhw mm0, mm3
  590.            pmullw mm1, mm3
  591.  
  592.            movq mm4, mm1
  593.            punpcklwd mm1, mm0
  594.            punpckhwd mm4, mm0
  595.            paddd mm1, mm4
  596.            psrad  mm1, 15
  597.            packssdw mm1, mm1
  598.            movd [edi], mm1
  599.            add edi, 4
  600.  
  601.            add eax, ebx
  602.            cmp eax, [r_end]
  603.            jb .l1
  604.            emms
  605.  
  606.  
  607.            sub edi, [dest]
  608.            mov eax, edi
  609.            ret
  610. endp
  611.  
  612.  
  613. proc m16_stereo stdcall, dest:dword,src:dword,\
  614.                        r_dt:dword, r_size:dword,r_end:dword
  615.  
  616.            mov esi, [src]
  617.            mov edi, [dest]
  618.            mov ecx, [r_size]
  619.            shr ecx,8
  620. @@:
  621.            call m16_s_mmx
  622.            add edi, 128
  623.            add esi, 64
  624.            call m16_s_mmx
  625.            add edi, 128
  626.            add esi, 64
  627.            call m16_s_mmx
  628.            add edi, 128
  629.            add esi, 64
  630.            call m16_s_mmx
  631.            add edi, 128
  632.            add esi, 64
  633.            dec ecx
  634.            jnz @b
  635.  
  636.            mov eax, [r_size]
  637.            add eax, eax
  638.            ret
  639. endp
  640.  
  641. align 4
  642. proc s8_stereo stdcall, dest:dword,src:dword,\
  643.                        r_dt:dword, r_size:dword,r_end:dword
  644.  
  645.            mov esi, [src]
  646.            mov edi, [dest]
  647.            mov ecx, [r_size]
  648.            shr ecx, 7
  649.  
  650.            movq mm7, [mm80]
  651.            movq mm6, [mm_mask]
  652. @@:
  653.            call s8_s_mmx
  654.            add edi, 64
  655.            add esi, 32
  656.            call s8_s_mmx
  657.            add edi, 64
  658.            add esi, 32
  659.            call s8_s_mmx
  660.            add edi, 64
  661.            add esi, 32
  662.            call s8_s_mmx
  663.            add edi, 64
  664.            add esi, 32
  665.            dec ecx
  666.            jnz @b
  667.  
  668.            mov eax, [r_size]
  669.            add eax, eax
  670.            ret
  671. endp
  672.  
  673. proc m8_stereo stdcall, dest:dword,src:dword,\
  674.                        r_dt:dword, r_size:dword,r_end:dword
  675.  
  676.            mov esi, [src]
  677.            mov edi, [dest]
  678.            mov ecx, [r_size]
  679.            shr ecx, 6
  680.  
  681.            movq mm7, [mm80]
  682.            movq mm6, [mm_mask]
  683. @@:
  684.            call m8_s_mmx
  685.            add edi, 64
  686.            add esi, 16
  687.            call m8_s_mmx
  688.            add edi, 64
  689.            add esi, 16
  690.            call m8_s_mmx
  691.            add edi, 64
  692.            add esi, 16
  693.            call m8_s_mmx
  694.            add edi, 64
  695.            add esi, 16
  696.                   dec ecx
  697.            jnz @b
  698.  
  699.            mov eax, [r_size]
  700.            add eax, eax
  701.            add eax, eax
  702.            ret
  703. endp
  704.  
  705. align 4
  706. proc alloc_mix_buff
  707.  
  708.            bsf eax, [mix_buff_map]
  709.            jnz .find
  710.            xor eax, eax
  711.            ret
  712. .find:
  713.            btr [mix_buff_map], eax
  714.            shl eax, 9
  715.            add eax, [mix_buff]
  716.            ret
  717. endp
  718.  
  719. align 4
  720. proc m16_s_mmx
  721.  
  722.            movq    mm0, [esi]
  723.            movq    mm1, mm0
  724.            punpcklwd mm0, mm0
  725.            punpckhwd mm1, mm1
  726.            movq    [edi], mm0
  727.            movq    [edi+8], mm1
  728.  
  729.            movq    mm0, [esi+8]
  730.            movq    mm1, mm0
  731.            punpcklwd mm0, mm0
  732.            punpckhwd mm1, mm1
  733.            movq    [edi+16], mm0
  734.            movq    [edi+24], mm1
  735.  
  736.            movq    mm0, [esi+16]
  737.            movq    mm1, mm0
  738.            punpcklwd mm0, mm0
  739.            punpckhwd mm1, mm1
  740.            movq    [edi+32], mm0
  741.            movq    [edi+40], mm1
  742.  
  743.            movq    mm0, [esi+24]
  744.            movq    mm1, mm0
  745.            punpcklwd mm0, mm0
  746.            punpckhwd mm1, mm1
  747.            movq    [edi+48], mm0
  748.            movq    [edi+56], mm1
  749.  
  750.            movq    mm0, [esi+32]
  751.            movq    mm1, mm0
  752.            punpcklwd mm0, mm0
  753.            punpckhwd mm1, mm1
  754.            movq    [edi+64], mm0
  755.            movq    [edi+72], mm1
  756.  
  757.            movq    mm0, [esi+40]
  758.            movq    mm1, mm0
  759.            punpcklwd mm0, mm0
  760.            punpckhwd mm1, mm1
  761.            movq    [edi+80], mm0
  762.            movq    [edi+88], mm1
  763.  
  764.  
  765.            movq    mm0, [esi+48]
  766.            movq    mm1, mm0
  767.            punpcklwd mm0, mm0
  768.            punpckhwd mm1, mm1
  769.            movq    [edi+96], mm0
  770.            movq    [edi+104], mm1
  771.  
  772.            movq    mm0, [esi+56]
  773.            movq    mm1, mm0
  774.            punpcklwd mm0, mm0
  775.            punpckhwd mm1, mm1
  776.            movq    [edi+112], mm0
  777.            movq    [edi+120], mm1
  778.  
  779.            ret
  780. endp
  781.  
  782. align 4
  783. proc s8_s_mmx
  784.  
  785.            movq    mm0, [esi]
  786.            psubb   mm0, mm7
  787.            movq    mm1, mm0
  788.            punpcklbw mm0, mm0
  789.            pand mm0, mm6
  790.            punpckhbw mm1, mm1
  791.            pand mm1, mm6
  792.            movq    [edi], mm0
  793.            movq    [edi+8], mm1
  794.  
  795.            movq    mm0, [esi+8]
  796.            psubb   mm0, mm7
  797.            movq    mm1, mm0
  798.            punpcklbw mm0, mm0
  799.            pand mm0, mm6
  800.            punpckhbw mm1, mm1
  801.            pand mm1, mm6
  802.            movq    [edi+16], mm0
  803.            movq    [edi+24], mm1
  804.  
  805.            movq    mm0, [esi+16]
  806.            psubb   mm0, mm7
  807.            movq    mm1, mm0
  808.            punpcklbw mm0, mm0
  809.            pand mm0, mm6
  810.            punpckhbw mm1, mm1
  811.            pand mm1, mm6
  812.            movq    [edi+32], mm0
  813.            movq    [edi+40], mm1
  814.  
  815.            movq    mm0, [esi+24]
  816.            psubb   mm0, mm7
  817.            movq    mm1, mm0
  818.            punpcklbw mm0, mm0
  819.            pand    mm0, mm6
  820.            punpckhbw mm1, mm1
  821.            pand    mm1, mm6
  822.            movq    [edi+48], mm0
  823.            movq    [edi+56], mm1
  824.  
  825.            ret
  826.  
  827. endp
  828.  
  829. align 4
  830. proc m8_s_mmx
  831.  
  832.            movq    mm0, [esi]
  833.            psubb   mm0, mm7
  834.            movq    mm1, mm0
  835.            punpcklbw mm0, mm0
  836.            pand mm0, mm6
  837.            punpckhbw mm1, mm1
  838.            pand mm1, mm6
  839.            movq mm2, mm0
  840.            punpcklwd mm0, mm0
  841.            punpckhwd mm2, mm2
  842.  
  843.            movq mm3, mm1
  844.            punpcklwd mm1, mm1
  845.            punpckhwd mm3, mm3
  846.  
  847.            movq    [edi], mm0
  848.            movq    [edi+8], mm2
  849.            movq    [edi+16], mm1
  850.            movq    [edi+24], mm3
  851.  
  852.            movq    mm0, [esi+8]
  853.            psubb   mm0, mm7
  854.            movq    mm1, mm0
  855.            punpcklbw mm0, mm0
  856.            pand mm0, mm6
  857.            punpckhbw mm1, mm1
  858.            pand mm1, mm6
  859.            movq mm2, mm0
  860.            punpcklwd mm0, mm0
  861.            punpckhwd mm2, mm2
  862.  
  863.            movq mm3, mm1
  864.            punpcklwd mm1, mm1
  865.            punpckhwd mm3, mm3
  866.  
  867.            movq    [edi+32], mm0
  868.            movq    [edi+40], mm2
  869.            movq    [edi+48], mm1
  870.            movq    [edi+56], mm3
  871.  
  872.            ret
  873. endp
  874.  
  875. align 4
  876. proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword
  877.  
  878.            mov edi, [output]
  879.            mov eax, [str0]
  880.            mov ebx, [str1]
  881.            mov esi, 128
  882.            call [mix_2_core]   ;edi, eax, ebx
  883.  
  884.            add edi, esi
  885.            add eax, esi
  886.            add ebx, esi
  887.            call [mix_2_core]   ;edi, eax, ebx
  888.  
  889.            add edi, esi
  890.            add eax, esi
  891.            add ebx, esi
  892.            call [mix_2_core]   ;edi, eax, ebx
  893.  
  894.            add edi, esi
  895.            add eax, esi
  896.            add ebx, esi
  897.            call [mix_2_core]   ;edi, eax, ebx
  898.            ret
  899. endp
  900.  
  901. align 4
  902. proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword
  903.  
  904.            mov edi, [output]
  905.            mov eax, [str0]
  906.            mov ebx, [str1]
  907.            mov ecx, [str2]
  908.            mov esi, 128
  909.            call [mix_3_core]
  910.  
  911.            add edi, esi
  912.            add eax, esi
  913.            add ebx, esi
  914.            add ecx, esi
  915.            call [mix_3_core]
  916.  
  917.            add edi, esi
  918.            add eax, esi
  919.            add ebx, esi
  920.            add ecx, esi
  921.            call [mix_3_core]
  922.  
  923.            add edi, esi
  924.            add eax, esi
  925.            add ebx, esi
  926.            add ecx, esi
  927.            call [mix_3_core]
  928.            ret
  929. endp
  930.  
  931. align 4
  932. proc mix_4_1 stdcall, str0:dword, str1:dword,\
  933.                       str2:dword, str3:dword
  934.  
  935.            local output:DWORD
  936.  
  937.            call alloc_mix_buff
  938.            and eax, eax
  939.            jz .err
  940.  
  941.            mov [output], eax
  942.  
  943.            mov edi, eax
  944.            mov eax, [str0]
  945.            mov ebx, [str1]
  946.            mov ecx, [str2]
  947.            mov edx, [str3]
  948.            mov esi, 128
  949.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  950.  
  951.            add edi, esi
  952.            add eax, esi
  953.            add ebx, esi
  954.            add ecx, esi
  955.            add edx, esi
  956.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  957.  
  958.            add edi, esi
  959.            add eax, esi
  960.            add ebx, esi
  961.            add ecx, esi
  962.            add edx, esi
  963.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  964.  
  965.            add edi, esi
  966.            add eax, esi
  967.            add ebx, esi
  968.            add ecx, esi
  969.            add edx, esi
  970.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  971.            mov eax, [output]
  972.            ret
  973. .err:
  974.            xor eax, eax
  975.            ret
  976. endp
  977.  
  978.  
  979. align 4
  980. proc final_mix stdcall, output:dword, str0:dword, str1:dword,\
  981.                         str2:dword, str3:dword
  982.  
  983.            mov edi, [output]
  984.  
  985.            mov eax, [str0]
  986.            mov ebx, [str1]
  987.            mov ecx, [str2]
  988.            mov edx, [str3]
  989.            mov esi, 128
  990.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  991.  
  992.            add edi, esi
  993.            add eax, esi
  994.            add ebx, esi
  995.            add ecx, esi
  996.            add edx, esi
  997.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  998.  
  999.            add edi, esi
  1000.            add eax, esi
  1001.            add ebx, esi
  1002.            add ecx, esi
  1003.            add edx, esi
  1004.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  1005.  
  1006.            add edi, esi
  1007.            add eax, esi
  1008.            add ebx, esi
  1009.            add ecx, esi
  1010.            add edx, esi
  1011.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  1012.            ret
  1013. endp
  1014.  
  1015. align 4
  1016. proc copy_mem stdcall, output:dword, input:dword
  1017.  
  1018.            mov edi, [output]
  1019.            mov esi, [input]
  1020.            mov ecx, 0x80
  1021. .l1:
  1022.            mov eax, [esi]
  1023.            mov [edi], eax
  1024.            add esi, 4
  1025.            add edi, 4
  1026.            loop .l1
  1027.  
  1028.            ret
  1029. endp
  1030.  
  1031. proc memcpy
  1032. @@:
  1033.            mov eax, [esi]
  1034.            mov [edi], eax
  1035.            add esi, 4
  1036.            add edi, 4
  1037.            dec ecx
  1038.            jnz @B
  1039.            ret
  1040. endp
  1041.  
  1042. if 0
  1043.  
  1044. align 4
  1045. proc new_mix stdcall, output:dword
  1046.            locals
  1047.              mixCounter  dd ?
  1048.              mixIndex  dd ?
  1049.              streamIndex dd ?
  1050.              inputCount  dd ?
  1051.              main_count  dd ?
  1052.              blockCount  dd ?
  1053.              mix_out  dd ?
  1054.            endl
  1055.  
  1056.            call prepare_playlist
  1057.  
  1058.            cmp [play_count], 0
  1059.            je .exit
  1060.            call FpuSave
  1061.            mov [main_count], 32;
  1062. .l00:
  1063.            mov [mix_buff_map], 0x0000FFFF;
  1064.            xor eax, eax
  1065.            mov [mixCounter], eax
  1066.            mov [mixIndex],eax
  1067.            mov [streamIndex], eax;
  1068.            mov ebx, [play_count]
  1069.            mov [inputCount], ebx
  1070. .l0:
  1071.            mov ecx, 4
  1072. .l1:
  1073.            mov ebx, [streamIndex]
  1074.            mov esi, [play_list+ebx*4]
  1075.            mov eax, [esi+STREAM.work_read]
  1076.            add [esi+STREAM.work_read], 512
  1077.  
  1078.            mov ebx, [mixIndex]
  1079.            mov [mix_input+ebx*4], eax
  1080.            inc [mixCounter]
  1081.            inc [mixIndex]
  1082.            inc [streamIndex]
  1083.            dec [inputCount]
  1084.            jz .m2
  1085.  
  1086.            dec ecx
  1087.            jnz .l1
  1088.  
  1089.            cmp [mixCounter], 4
  1090.            jnz .m2
  1091.  
  1092.            stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12]
  1093.            sub [mixIndex],4
  1094.            mov ebx, [mixIndex]
  1095.            mov [mix_input+ebx*4], eax
  1096.            inc [mixIndex]
  1097.            mov [mixCounter], 0
  1098.  
  1099.            cmp [inputCount], 0
  1100.            jnz .l0
  1101. .m2:
  1102.            cmp [mixIndex], 1
  1103.            jne @f
  1104.            stdcall copy_mem, [output], [mix_input]
  1105.            jmp .m3
  1106. @@:
  1107.            cmp [mixIndex], 2
  1108.            jne @f
  1109.            stdcall mix_2_1, [output], [mix_input], [mix_input+4]
  1110.            jmp .m3
  1111. @@:
  1112.            cmp [mixIndex], 3
  1113.            jne @f
  1114.            stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8]
  1115.            jmp .m3
  1116. @@:
  1117.            stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12]
  1118. .m3:
  1119.            add [output],512
  1120.  
  1121.            dec [main_count]
  1122.            jnz .l00
  1123.  
  1124.            call update_stream
  1125.            emms
  1126.            call FpuRestore
  1127.            ret
  1128. .exit:
  1129.            mov edi, [output]
  1130.            mov ecx, 0x1000
  1131.            xor eax, eax
  1132.            cld
  1133.            rep stosd
  1134.            ret
  1135. endp
  1136.  
  1137. end if
  1138.  
  1139.