Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
694 serge 3
;; Copyright (C) KolibriOS team 2006-2008. 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
 
378 serge 23
           mov [main_count], 32
281 serge 24
           call prepare_playlist
378 serge 25
           cmp [play_count], 0
26
           je .clear
168 serge 27
 
378 serge 28
           lea eax, [fpu_state+16]
29
           and eax, -16             ;must be 16b aligned
188 serge 30
           call FpuSave
168 serge 31
 
378 serge 32
           call update_stream
33
.mix:
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
 
695 serge 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
@@:
697 serge 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
 
378 serge 60
           lea ebx, [mix_list]
61
           stdcall mix_all, [output], ebx, eax
695 serge 62
.next:
378 serge 63
           add [output], 512
293 serge 64
           dec [main_count]
378 serge 65
           jnz .mix
66
.exit:
67
           lea eax, [fpu_state+16]
68
           and eax, -16
188 serge 69
           call FpuRestore
281 serge 70
           ret
378 serge 71
.done:
72
           mov ecx, [main_count]
73
           shl ecx, 7     ;ecx*= 512/4
74
 
281 serge 75
           mov edi, [output]
76
           xor eax, eax
77
           cld
78
           rep stosd
378 serge 79
           jmp .exit
80
.clear:
81
           mov edi, [output]
82
           mov ecx, 4096
83
           xor eax, eax
84
           cld
85
           rep stosd
281 serge 86
           ret
168 serge 87
endp
88
 
89
align 4
90
proc update_stream
281 serge 91
           locals
170 serge 92
             stream_index  dd ?
568 serge 93
             event         rd 6
281 serge 94
           endl
168 serge 95
 
281 serge 96
           mov [stream_index], 0
168 serge 97
.l1:
281 serge 98
           mov edx, [stream_index]
99
           mov esi, [play_list+edx*4]
168 serge 100
 
378 serge 101
           mov eax, [esi+STREAM.out_rp]
102
           cmp eax, [esi+STREAM.out_top]
281 serge 103
           jb @f
328 serge 104
           sub eax, 64*1024
168 serge 105
@@:
378 serge 106
           mov [esi+STREAM.out_rp], eax
168 serge 107
 
378 serge 108
           cmp [esi+STREAM.out_count], 16384
109
           ja .skip
168 serge 110
 
378 serge 111
           test [esi+STREAM.format], PCM_RING
112
           jnz .ring
168 serge 113
 
281 serge 114
           stdcall refill, esi
378 serge 115
.skip:
281 serge 116
           inc [stream_index]
117
           dec [play_count]
118
           jnz .l1
119
           ret
378 serge 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
168 serge 137
@@:
378 serge 138
           mov eax, [ebx+STREAM.in_count]
139
           test eax, eax
140
           jz .done
227 serge 141
 
378 serge 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]
168 serge 189
           test eax, eax
378 serge 190
           jz .exit
227 serge 191
 
378 serge 192
           mov ebx, [ebx+STREAM.notify_id]
1058 Galkov 193
           mov edx, EVENT_WATCHED
194
           xor esi, esi
195
           call RaiseEvent   ;eax, ebx, edx, esi
378 serge 196
.exit:
281 serge 197
           ret
168 serge 198
endp
199
 
200
align 4
378 serge 201
proc refill_ring stdcall, str:dword
281 serge 202
           locals
378 serge 203
             event     rd 6
281 serge 204
           endl
168 serge 205
 
281 serge 206
           mov ebx, [str]
378 serge 207
           mov edi, [ebx+STREAM.out_wp]
208
           cmp edi, [ebx+STREAM.out_top]
328 serge 209
           jb @F
378 serge 210
           sub edi, 0x10000
211
           mov [ebx+STREAM.out_wp], edi
328 serge 212
@@:
378 serge 213
           mov ecx, [ebx+STREAM.r_size]
214
           mov eax, ecx
215
           cmp word [ebx+STREAM.format], PCM_1_16_8
216
           ja @F
168 serge 217
 
378 serge 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
 
285 serge 230
           stdcall [ebx+STREAM.resample], edi, esi, \
378 serge 231
           [ebx+STREAM.r_dt], ecx, eax
168 serge 232
 
281 serge 233
           mov ebx, [str]
168 serge 234
 
378 serge 235
           add [ebx+STREAM.out_count], eax;
236
           add [ebx+STREAM.out_wp], eax;
168 serge 237
 
378 serge 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]
281 serge 245
           jb @f
246
 
378 serge 247
           sub eax, [ebx+STREAM.in_size]
168 serge 248
@@:
378 serge 249
           mov [ebx+STREAM.in_rp], eax
168 serge 250
 
378 serge 251
           sub eax, [ebx+STREAM.in_base]
252
           sub eax, 128
1058 Galkov 253
           lea esi, [event]
378 serge 254
 
1058 Galkov 255
           mov dword [esi], RT_INP_EMPTY
256
           mov dword [esi+4], 0
257
           mov dword [esi+8], ebx
258
           mov dword [esi+12], eax
378 serge 259
 
260
           mov eax, [ebx+STREAM.notify_event]
261
           test eax, eax
262
           jz .exit
263
 
264
           mov ebx, [ebx+STREAM.notify_id]
1058 Galkov 265
           xor edx, edx
266
           call RaiseEvent   ;eax, ebx, edx, esi
378 serge 267
.exit:
268
           ret
269
endp
168 serge 270
 
694 serge 271
if USE_SSE2_MIXER
272
 
378 serge 273
align 4
274
proc mix_all stdcall, dest:dword, list:dword, count:dword
275
 
276
           mov edi, [dest]
694 serge 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
695 serge 296
           cvtdq2ps xmm0, xmm0
297
           cvtdq2ps xmm1, xmm1
694 serge 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
 
695 serge 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
697 serge 362
           add eax, 16
695 serge 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
 
697 serge 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
 
694 serge 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]
378 serge 460
           mov ebx, 64
461
.mix:
462
           mov edx, [list]
463
           mov ecx, [count]
464
 
465
           mov eax, [edx]
694 serge 466
 
378 serge 467
           movq mm0, [eax]
694 serge 468
 
378 serge 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
694 serge 476
           add edx, 12
378 serge 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
168 serge 488
@@:
378 serge 489
           movq [edi], mm0
490
           add edi, 8
491
           dec ebx
492
           jnz .mix
227 serge 493
 
291 serge 494
           ret
168 serge 495
endp
496
 
694 serge 497
end if
498
 
499
 
168 serge 500
align 4
285 serge 501
proc resample_1 stdcall, dest:dword,src:dword,\
291 serge 502
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 503
 
285 serge 504
; dest equ esp+8
505
; src  equ esp+12
506
; r_dt equ esp+16
507
; r_size equ esp+20
378 serge 508
; r_end equ esp+24
168 serge 509
 
285 serge 510
           mov edi, [dest]
511
           mov edx, [src]
512
           sub edx, 32*2
513
           mov eax, 16
168 serge 514
 
378 serge 515
align 4
168 serge 516
.l1:
291 serge 517
           mov ecx, eax
518
           mov esi, eax
519
           and ecx, 0x7FFF
520
           shr esi, 15
521
           lea esi, [edx+esi*2]
168 serge 522
 
291 serge 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
168 serge 535
@@:
291 serge 536
           cmp ecx, -32768        ; ffff8000H
537
           jge .write
538
           mov ecx, -32768        ; ffff8000H
168 serge 539
.write:
291 serge 540
           mov ebx, ecx
541
           shl ebx, 16
542
           mov bx, cx
543
           mov [edi], ebx
544
           add edi, 4
168 serge 545
 
293 serge 546
           add eax, [esp+16]
547
           cmp eax, [esp+24]
291 serge 548
           jb .l1
168 serge 549
 
291 serge 550
           mov ebp, esp
168 serge 551
 
291 serge 552
           sub edi, [dest]
553
           mov eax, edi
554
           ret
168 serge 555
endp
556
 
557
align 4
285 serge 558
proc resample_18 stdcall, dest:dword,src:dword,\
291 serge 559
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 560
 
561
 
291 serge 562
           mov edi, [dest]
285 serge 563
           mov edx, [src]
564
           sub edx, 32
565
 
291 serge 566
           mov esi, 16
168 serge 567
 
378 serge 568
align 4
168 serge 569
.l1:
291 serge 570
           mov ecx, esi
571
           mov eax, esi
572
           and ecx, 0x7FFF
573
           shr eax, 15
574
           lea eax, [edx+eax]
168 serge 575
 
291 serge 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
168 serge 593
@@:
291 serge 594
           cmp ecx, -32768        ; ffff8000H
595
           jge .write
596
           mov ecx, -32768        ; ffff8000H
168 serge 597
.write:
291 serge 598
           mov ebx, ecx
599
           shl ebx, 16
600
           mov bx, cx
601
           mov [edi], ebx
602
           add edi, 4
168 serge 603
 
293 serge 604
           add esi, [esp+16]
605
           cmp esi, [esp+24]
291 serge 606
           jb .l1
168 serge 607
 
291 serge 608
           mov ebp, esp
609
           sub edi, [dest]
610
           mov eax, edi
611
           ret
168 serge 612
endp
613
 
614
align 4
285 serge 615
proc copy_stream stdcall, dest:dword,src:dword,\
291 serge 616
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 617
 
281 serge 618
           mov ecx, [r_size]
619
           mov eax, ecx
620
           shr ecx, 2
621
           mov esi, [src]
622
           mov edi, [dest]
575 serge 623
           cld
281 serge 624
           rep movsd
625
           ret
168 serge 626
endp
627
 
628
align 4
285 serge 629
proc resample_2 stdcall, dest:dword,src:dword,\
291 serge 630
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 631
 
285 serge 632
           mov edx, [src]
633
           sub edx, 32*4
634
           mov edi, [dest]
635
           mov ebx, [r_dt]
636
           mov eax, 16
637
           emms
168 serge 638
 
378 serge 639
align 4
168 serge 640
.l1:
285 serge 641
           mov ecx, eax
642
           mov esi, eax
643
           and ecx, 0x7FFF
644
           shr esi, 15
645
           lea esi, [edx+esi*4]
168 serge 646
 
285 serge 647
           movq mm0, [esi]
648
           movq mm1, mm0
168 serge 649
 
285 serge 650
           movd mm2, ecx
651
           punpcklwd mm2, mm2
652
           movq mm3, qword [m7]    ;0x8000
168 serge 653
 
285 serge 654
           psubw mm3, mm2 ;        ;0x8000 - iconst
655
           punpckldq mm3, mm2
168 serge 656
 
285 serge 657
           pmulhw mm0, mm3
658
           pmullw mm1, mm3
168 serge 659
 
285 serge 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
168 serge 668
 
285 serge 669
           add eax, ebx
670
           cmp eax, [r_end]
671
           jb .l1
672
           emms
168 serge 673
 
285 serge 674
           sub edi, [dest]
675
           mov eax, edi
676
           ret
168 serge 677
endp
678
 
679
align 4
285 serge 680
proc resample_28 stdcall, dest:dword,src:dword,\
291 serge 681
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 682
 
285 serge 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]
168 serge 691
 
378 serge 692
align 4
168 serge 693
.l1:
291 serge 694
           mov ecx, eax
695
           mov esi, eax
696
           and ecx, 0x7FFF
697
           shr esi, 15
698
           lea esi, [edx+esi*2]
168 serge 699
 
291 serge 700
           movq mm0, [esi]
701
           psubb mm0,mm7
702
           punpcklbw mm0,mm0
703
           pand mm0,mm6
168 serge 704
 
291 serge 705
           movq mm1, mm0
168 serge 706
 
291 serge 707
           movd mm2, ecx
708
           punpcklwd mm2, mm2
709
           movq mm3, qword [m7] ;                  // 0x8000
168 serge 710
 
291 serge 711
           psubw mm3, mm2       ;         // 0x8000 - iconst
712
           punpckldq mm3, mm2
168 serge 713
 
291 serge 714
           pmulhw mm0, mm3
715
           pmullw mm1, mm3
168 serge 716
 
291 serge 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
168 serge 725
 
291 serge 726
           add eax, ebx
727
           cmp eax, [r_end]
728
           jb .l1
729
           emms
168 serge 730
 
731
 
291 serge 732
           sub edi, [dest]
733
           mov eax, edi
734
           ret
168 serge 735
endp
736
 
737
 
285 serge 738
proc m16_stereo stdcall, dest:dword,src:dword,\
291 serge 739
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 740
 
291 serge 741
           mov esi, [src]
742
           mov edi, [dest]
743
           mov ecx, [r_size]
744
           shr ecx,8
168 serge 745
@@:
291 serge 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
168 serge 760
 
291 serge 761
           mov eax, [r_size]
762
           add eax, eax
763
           ret
168 serge 764
endp
765
 
766
align 4
285 serge 767
proc s8_stereo stdcall, dest:dword,src:dword,\
291 serge 768
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 769
 
281 serge 770
           mov esi, [src]
771
           mov edi, [dest]
772
           mov ecx, [r_size]
773
           shr ecx, 7
168 serge 774
 
281 serge 775
           movq mm7, [mm80]
776
           movq mm6, [mm_mask]
168 serge 777
@@:
281 serge 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
168 serge 790
           dec ecx
281 serge 791
           jnz @b
168 serge 792
 
281 serge 793
           mov eax, [r_size]
794
           add eax, eax
795
           ret
168 serge 796
endp
797
 
285 serge 798
proc m8_stereo stdcall, dest:dword,src:dword,\
291 serge 799
                       r_dt:dword, r_size:dword,r_end:dword
168 serge 800
 
281 serge 801
           mov esi, [src]
802
           mov edi, [dest]
803
           mov ecx, [r_size]
804
           shr ecx, 6
168 serge 805
 
281 serge 806
           movq mm7, [mm80]
807
           movq mm6, [mm_mask]
168 serge 808
@@:
281 serge 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
168 serge 823
 
281 serge 824
           mov eax, [r_size]
825
           add eax, eax
826
           add eax, eax
827
           ret
168 serge 828
endp
829
 
830
align 4
831
proc alloc_mix_buff
832
 
281 serge 833
           bsf eax, [mix_buff_map]
834
           jnz .find
835
           xor eax, eax
836
           ret
168 serge 837
.find:
281 serge 838
           btr [mix_buff_map], eax
839
           shl eax, 9
840
           add eax, [mix_buff]
841
           ret
168 serge 842
endp
843
 
293 serge 844
align 4
168 serge 845
proc m16_s_mmx
846
 
291 serge 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
168 serge 853
 
291 serge 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
168 serge 860
 
291 serge 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
168 serge 867
 
291 serge 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
168 serge 874
 
291 serge 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
168 serge 881
 
291 serge 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
168 serge 888
 
889
 
291 serge 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
168 serge 896
 
291 serge 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
168 serge 903
 
291 serge 904
           ret
168 serge 905
endp
906
 
907
align 4
908
proc s8_s_mmx
909
 
281 serge 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
168 serge 919
 
281 serge 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
168 serge 929
 
281 serge 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
168 serge 939
 
281 serge 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
168 serge 949
 
281 serge 950
           ret
168 serge 951
 
952
endp
953
 
954
align 4
955
proc m8_s_mmx
956
 
281 serge 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
168 serge 967
 
281 serge 968
           movq mm3, mm1
969
           punpcklwd mm1, mm1
970
           punpckhwd mm3, mm3
168 serge 971
 
281 serge 972
           movq    [edi], mm0
973
           movq    [edi+8], mm2
974
           movq    [edi+16], mm1
975
           movq    [edi+24], mm3
168 serge 976
 
281 serge 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
168 serge 987
 
281 serge 988
           movq mm3, mm1
989
           punpcklwd mm1, mm1
990
           punpckhwd mm3, mm3
168 serge 991
 
281 serge 992
           movq    [edi+32], mm0
993
           movq    [edi+40], mm2
994
           movq    [edi+48], mm1
995
           movq    [edi+56], mm3
168 serge 996
 
281 serge 997
           ret
168 serge 998
endp
999
 
1000
align 4
1001
proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword
1002
 
281 serge 1003
           mov edi, [output]
293 serge 1004
           mov eax, [str0]
1005
           mov ebx, [str1]
1006
           mov esi, 128
1007
           call [mix_2_core]   ;edi, eax, ebx
168 serge 1008
 
293 serge 1009
           add edi, esi
1010
           add eax, esi
1011
           add ebx, esi
1012
           call [mix_2_core]   ;edi, eax, ebx
168 serge 1013
 
293 serge 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
281 serge 1023
           ret
168 serge 1024
endp
1025
 
1026
align 4
1027
proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword
1028
 
291 serge 1029
           mov edi, [output]
293 serge 1030
           mov eax, [str0]
1031
           mov ebx, [str1]
1032
           mov ecx, [str2]
1033
           mov esi, 128
1034
           call [mix_3_core]
168 serge 1035
 
293 serge 1036
           add edi, esi
1037
           add eax, esi
1038
           add ebx, esi
1039
           add ecx, esi
1040
           call [mix_3_core]
168 serge 1041
 
293 serge 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]
291 serge 1053
           ret
168 serge 1054
endp
1055
 
1056
align 4
1057
proc mix_4_1 stdcall, str0:dword, str1:dword,\
291 serge 1058
                      str2:dword, str3:dword
168 serge 1059
 
291 serge 1060
           local output:DWORD
168 serge 1061
 
291 serge 1062
           call alloc_mix_buff
1063
           and eax, eax
1064
           jz .err
168 serge 1065
 
378 serge 1066
           mov [output], eax
1067
 
291 serge 1068
           mov edi, eax
293 serge 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
168 serge 1075
 
293 serge 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
291 serge 1096
           mov eax, [output]
1097
           ret
168 serge 1098
.err:
291 serge 1099
           xor eax, eax
1100
           ret
168 serge 1101
endp
1102
 
1103
 
1104
align 4
1105
proc final_mix stdcall, output:dword, str0:dword, str1:dword,\
291 serge 1106
                        str2:dword, str3:dword
168 serge 1107
 
291 serge 1108
           mov edi, [output]
168 serge 1109
 
281 serge 1110
           mov eax, [str0]
1111
           mov ebx, [str1]
1112
           mov ecx, [str2]
293 serge 1113
           mov edx, [str3]
1114
           mov esi, 128
1115
           call [mix_4_core]  ;edi, eax, ebx, ecx, edx
168 serge 1116
 
293 serge 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
168 serge 1123
 
293 serge 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
168 serge 1130
 
293 serge 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
281 serge 1137
           ret
168 serge 1138
endp
1139
 
1140
align 4
1141
proc copy_mem stdcall, output:dword, input:dword
1142
 
291 serge 1143
           mov edi, [output]
1144
           mov esi, [input]
1145
           mov ecx, 0x80
168 serge 1146
.l1:
291 serge 1147
           mov eax, [esi]
1148
           mov [edi], eax
1149
           add esi, 4
1150
           add edi, 4
1151
           loop .l1
168 serge 1152
 
291 serge 1153
           ret
168 serge 1154
endp
1155
 
1156
proc memcpy
1157
@@:
291 serge 1158
           mov eax, [esi]
1159
           mov [edi], eax
1160
           add esi, 4
1161
           add edi, 4
1162
           dec ecx
1163
           jnz @B
1164
           ret
168 serge 1165
endp
1166
 
378 serge 1167
if 0
168 serge 1168
 
378 serge 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