Subversion Repositories Kolibri OS

Rev

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

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