Subversion Repositories Kolibri OS

Rev

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

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