Subversion Repositories Kolibri OS

Rev

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

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