Subversion Repositories Kolibri OS

Rev

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