Subversion Repositories Kolibri OS

Rev

Rev 568 | Blame | Last modification | View Log | Download | RSS feed

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