Subversion Repositories Kolibri OS

Rev

Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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