Subversion Repositories Kolibri OS

Rev

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

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