Subversion Repositories Kolibri OS

Rev

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