Subversion Repositories Kolibri OS

Rev

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