Subversion Repositories Kolibri OS

Rev

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