Subversion Repositories Kolibri OS

Rev

Rev 1679 | 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
 
1679 serge 32
           call update_streams
378 serge 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
1679 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
 
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
 
1679 serge 101
           add dword [esi+STREAM.time_stamp], 4096
102
           adc dword [esi+STREAM.time_stamp+4], 0
1697 serge 103
           mov dword [esi+STREAM.last_ts], 0
1679 serge 104
 
378 serge 105
           mov eax, [esi+STREAM.out_rp]
106
           cmp eax, [esi+STREAM.out_top]
281 serge 107
           jb @f
328 serge 108
           sub eax, 64*1024
168 serge 109
@@:
378 serge 110
           mov [esi+STREAM.out_rp], eax
168 serge 111
 
378 serge 112
           cmp [esi+STREAM.out_count], 16384
113
           ja .skip
168 serge 114
 
378 serge 115
           test [esi+STREAM.format], PCM_RING
116
           jnz .ring
168 serge 117
 
281 serge 118
           stdcall refill, esi
378 serge 119
.skip:
281 serge 120
           inc [stream_index]
121
           dec [play_count]
122
           jnz .l1
123
           ret
378 serge 124
.ring:
125
           stdcall refill_ring, esi
126
           jmp .skip
127
endp
128
 
129
align 4
130
proc refill stdcall, str:dword
131
           locals
132
             r_size    rd 1
133
           endl
134
 
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
@@:
378 serge 142
           mov eax, [ebx+STREAM.in_count]
143
           test eax, eax
144
           jz .done
227 serge 145
 
378 serge 146
           mov ecx, [ebx+STREAM.r_size]
147
           cmp eax, ecx
148
           jle @F
149
 
150
           mov eax, ecx
151
@@:
152
           mov ecx, eax
153
           cmp word [ebx+STREAM.format], PCM_1_16_8
154
           ja @F
155
 
156
           shr eax, 1                   ;two channles
157
@@:
158
           test [ebx+STREAM.format], 1  ;even formats mono
159
           jz @F
160
 
161
           shr eax, 1                   ;eax= samples
162
@@:
163
           shl eax, 15    ;eax*=32768 =r_end
164
 
165
           mov [r_size], ecx
166
 
167
           mov esi, [ebx+STREAM.in_rp]
168
           mov edi, [ebx+STREAM.out_wp]
169
 
170
           stdcall [ebx+STREAM.resample], edi, esi, \
171
           [ebx+STREAM.r_dt], ecx, eax
172
 
173
           mov ebx, [str]
174
 
175
           add [ebx+STREAM.out_count], eax;
176
           add [ebx+STREAM.out_wp], eax;
177
 
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
183
 
184
           cmp eax, [ebx+STREAM.in_top]
185
           jb @f
186
 
187
           sub eax, [ebx+STREAM.in_size]
188
@@:
189
           mov [ebx+STREAM.in_rp], eax
190
 
191
.done:
192
           mov eax, [ebx+STREAM.notify_event]
168 serge 193
           test eax, eax
378 serge 194
           jz .exit
227 serge 195
 
378 serge 196
           mov ebx, [ebx+STREAM.notify_id]
1058 Galkov 197
           mov edx, EVENT_WATCHED
198
           xor esi, esi
199
           call RaiseEvent   ;eax, ebx, edx, esi
378 serge 200
.exit:
281 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
 
281 serge 210
           mov ebx, [str]
378 serge 211
           mov edi, [ebx+STREAM.out_wp]
212
           cmp edi, [ebx+STREAM.out_top]
328 serge 213
           jb @F
378 serge 214
           sub edi, 0x10000
215
           mov [ebx+STREAM.out_wp], edi
328 serge 216
@@:
378 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
 
378 serge 222
           shr eax, 1                   ;two channles
223
@@:
224
           test [ebx+STREAM.format], 1  ;even formats mono
225
           jz @F
226
 
227
           shr eax, 1                   ;eax= samples
228
@@:
229
           shl eax, 15    ;eax*=32768 =r_end
230
 
231
           mov esi, [ebx+STREAM.in_rp]
232
           mov edi, [ebx+STREAM.out_wp]
233
 
285 serge 234
           stdcall [ebx+STREAM.resample], edi, esi, \
378 serge 235
           [ebx+STREAM.r_dt], ecx, eax
168 serge 236
 
281 serge 237
           mov ebx, [str]
168 serge 238
 
378 serge 239
           add [ebx+STREAM.out_count], eax;
240
           add [ebx+STREAM.out_wp], eax;
168 serge 241
 
378 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
247
 
248
           cmp eax, [ebx+STREAM.in_top]
281 serge 249
           jb @f
250
 
378 serge 251
           sub eax, [ebx+STREAM.in_size]
168 serge 252
@@:
378 serge 253
           mov [ebx+STREAM.in_rp], eax
168 serge 254
 
378 serge 255
           sub eax, [ebx+STREAM.in_base]
256
           sub eax, 128
1058 Galkov 257
           lea esi, [event]
378 serge 258
 
1058 Galkov 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
 
264
           mov eax, [ebx+STREAM.notify_event]
265
           test eax, eax
266
           jz .exit
267
 
268
           mov ebx, [ebx+STREAM.notify_id]
1058 Galkov 269
           xor edx, edx
270
           call RaiseEvent   ;eax, ebx, edx, esi
378 serge 271
.exit:
272
           ret
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
 
280
           mov edi, [dest]
694 serge 281
           mov ebx, 32
282
.mix:
283
           mov edx, [list]
284
           mov ecx, [count]
285
 
286
           mov eax, [edx]
287
 
288
           movdqa xmm1, [eax]
289
           movss xmm2, [edx+4]
290
           movss xmm3, [edx+8]
291
 
292
           punpcklwd xmm0, xmm1
293
           punpckhwd xmm1, xmm1
294
 
295
           shufps xmm2, xmm3, 0
296
           shufps xmm2, xmm2, 0x88
297
 
298
           psrad xmm0, 16
299
           psrad xmm1, 16
695 serge 300
           cvtdq2ps xmm0, xmm0
301
           cvtdq2ps xmm1, xmm1
694 serge 302
           mulps xmm0, xmm2
303
           mulps xmm1, xmm2
304
 
305
.mix_loop:
306
           add dword [edx], 16
307
           add edx, 12
308
           dec ecx
309
           jz @F
310
 
311
           mov eax, [edx]
312
 
313
           movdqa xmm3, [eax]
314
           movss xmm4, [edx+4]
315
           movss xmm5, [edx+8]
316
 
317
           punpcklwd xmm2, xmm3
318
           punpckhwd xmm3, xmm3
319
 
320
           shufps xmm4, xmm5, 0
321
           shufps xmm4, xmm4, 0x88
322
 
323
           psrad xmm2, 16
324
           psrad xmm3, 16
325
 
326
           cvtdq2ps xmm2, xmm2
327
           cvtdq2ps xmm3, xmm3
328
 
329
           mulps xmm2, xmm4
330
           mulps xmm3, xmm4
331
           addps xmm0, xmm2
332
           addps xmm1, xmm3
333
 
334
           jmp .mix_loop
335
@@:
336
           cvtps2dq xmm0, xmm0
337
           cvtps2dq xmm1, xmm1
338
           packssdw xmm0, xmm0
339
           packssdw xmm1, xmm1
340
           punpcklqdq xmm0, xmm1
341
           movntdq [edi], xmm0
342
 
343
           add edi, 16
344
           dec ebx
345
           jnz .mix
346
 
347
           ret
348
endp
349
 
695 serge 350
; param
351
;  edi = dest
352
;  edx = mix_list
353
 
354
align 4
355
mix_fast:
356
 
357
           mov ebx, 32
358
           mov eax, [edx]
359
 
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
364
.mix:
365
           movdqa xmm1, [eax]        ; R3w L3w  R2w L2w  R1w L1w  R0w L0w
697 serge 366
           add eax, 16
695 serge 367
           punpcklwd xmm0, xmm1      ; R1w R1w  L1w L1W  R0w R0w  L0w L0w
368
           punpckhwd xmm1, xmm1      ; R3w R3w  L3w L3w  R2w R2w  L2w L2w
369
 
370
           psrad xmm0, 16            ; R1d L1d R0d L0d
371
           psrad xmm1, 16            ; R3d L3d R2d L2d
372
 
373
           cvtdq2ps xmm0, xmm0       ; time to use all power
374
           cvtdq2ps xmm1, xmm1       ; of the dark side
375
 
376
           mulps xmm0, xmm2          ; R1f' L1f' R0f' L0f'
377
           mulps xmm1, xmm2          ; R3f' L3f' R2f' L2f'
378
 
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
385
 
386
           add edi, 16
387
           dec ebx
388
           jnz .mix
389
 
390
           ret
391
 
697 serge 392
align 4
393
mix_fast_2_stream:
394
 
395
           mov ebx, 32
396
           mov eax, [edx]
397
 
398
           movss xmm4, [edx+4]       ; vol Lf
399
           movss xmm5, [edx+8]       ; vol Rf
400
           mov ecx, [edx+12]
401
 
402
           movss xmm6, [edx+16]      ; vol Lf
403
           movss xmm7, [edx+20]      ; vol Rf
404
 
405
           shufps xmm4, xmm5, 0      ; Rf Rf Lf Lf
406
           shufps xmm4, xmm4, 0x88   ; volume level  Rf Lf Rf Lf
407
 
408
           shufps xmm6, xmm7, 0      ; Rf Rf Lf Lf
409
           shufps xmm6, xmm6, 0x88   ; volume level  Rf Lf Rf Lf
410
 
411
.mix:
412
           movdqa xmm1, [eax]        ; R3w L3w  R2w L2w  R1w L1w  R0w L0w
413
           movdqa xmm3, [ecx]        ; R3w L3w  R2w L2w  R1w L1w  R0w L0w
414
 
415
           add eax, 16
416
           add ecx, 16
417
 
418
           punpcklwd xmm0, xmm1      ; R1w R1w  L1w L1W  R0w R0w  L0w L0w
419
           punpckhwd xmm1, xmm1      ; R3w R3w  L3w L3w  R2w R2w  L2w L2w
420
 
421
           psrad xmm0, 16            ; R1d L1d R0d L0d
422
           psrad xmm1, 16            ; R3d L3d R2d L2d
423
 
424
           cvtdq2ps xmm0, xmm0       ; time to use all power
425
           cvtdq2ps xmm1, xmm1       ; of the dark side
426
 
427
           mulps xmm0, xmm4          ; R1f' L1f' R0f' L0f'
428
           mulps xmm1, xmm4          ; R3f' L3f' R2f' L2f'
429
 
430
           punpcklwd xmm2, xmm3      ; R1w R1w  L1w L1W  R0w R0w  L0w L0w
431
           punpckhwd xmm3, xmm3      ; R3w R3w  L3w L3w  R2w R2w  L2w L2w
432
 
433
           psrad xmm2, 16            ; R1d L1d R0d L0d
434
           psrad xmm3, 16            ; R3d L3d R2d L2d
435
 
436
           cvtdq2ps xmm2, xmm2       ; time to use all power
437
           cvtdq2ps xmm3, xmm3       ; of the dark side
438
 
439
           mulps xmm2, xmm6          ; R1f' L1f' R0f' L0f'
440
           mulps xmm3, xmm6          ; R3f' L3f' R2f' L2f'
441
 
442
           addps xmm0, xmm2
443
           addps xmm1, xmm3
444
 
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
451
 
452
           add edi, 16
453
           dec ebx
454
           jnz .mix
455
 
456
           ret
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
 
463
           mov edi, [dest]
378 serge 464
           mov ebx, 64
465
.mix:
466
           mov edx, [list]
467
           mov ecx, [count]
468
 
469
           mov eax, [edx]
694 serge 470
 
378 serge 471
           movq mm0, [eax]
694 serge 472
 
378 serge 473
           movd mm1, [edx+4]
474
           punpckldq mm1,mm1
475
           pmulhw mm0, mm1
476
           psllw  mm0, 1
477
 
478
.mix_loop:
479
           add dword [edx], 8
694 serge 480
           add edx, 12
378 serge 481
           dec ecx
482
           jz @F
483
 
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
@@:
378 serge 493
           movq [edi], mm0
494
           add edi, 8
495
           dec ebx
496
           jnz .mix
227 serge 497
 
291 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
 
285 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:
291 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
 
291 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
@@:
291 serge 540
           cmp ecx, -32768        ; ffff8000H
541
           jge .write
542
           mov ecx, -32768        ; ffff8000H
168 serge 543
.write:
291 serge 544
           mov ebx, ecx
545
           shl ebx, 16
546
           mov bx, cx
547
           mov [edi], ebx
548
           add edi, 4
168 serge 549
 
293 serge 550
           add eax, [esp+16]
551
           cmp eax, [esp+24]
291 serge 552
           jb .l1
168 serge 553
 
291 serge 554
           mov ebp, esp
168 serge 555
 
291 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
 
291 serge 566
           mov edi, [dest]
285 serge 567
           mov edx, [src]
568
           sub edx, 32
569
 
291 serge 570
           mov esi, 16
168 serge 571
 
378 serge 572
align 4
168 serge 573
.l1:
291 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
 
291 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
@@:
291 serge 598
           cmp ecx, -32768        ; ffff8000H
599
           jge .write
600
           mov ecx, -32768        ; ffff8000H
168 serge 601
.write:
291 serge 602
           mov ebx, ecx
603
           shl ebx, 16
604
           mov bx, cx
605
           mov [edi], ebx
606
           add edi, 4
168 serge 607
 
293 serge 608
           add esi, [esp+16]
609
           cmp esi, [esp+24]
291 serge 610
           jb .l1
168 serge 611
 
291 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
 
281 serge 622
           mov ecx, [r_size]
623
           mov eax, ecx
624
           shr ecx, 2
625
           mov esi, [src]
626
           mov edi, [dest]
575 serge 627
           cld
281 serge 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
 
285 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:
285 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
 
285 serge 651
           movq mm0, [esi]
652
           movq mm1, mm0
168 serge 653
 
285 serge 654
           movd mm2, ecx
655
           punpcklwd mm2, mm2
656
           movq mm3, qword [m7]    ;0x8000
168 serge 657
 
285 serge 658
           psubw mm3, mm2 ;        ;0x8000 - iconst
659
           punpckldq mm3, mm2
168 serge 660
 
285 serge 661
           pmulhw mm0, mm3
662
           pmullw mm1, mm3
168 serge 663
 
285 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
 
285 serge 673
           add eax, ebx
674
           cmp eax, [r_end]
675
           jb .l1
676
           emms
168 serge 677
 
285 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
 
285 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:
291 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
 
291 serge 704
           movq mm0, [esi]
705
           psubb mm0,mm7
706
           punpcklbw mm0,mm0
707
           pand mm0,mm6
168 serge 708
 
291 serge 709
           movq mm1, mm0
168 serge 710
 
291 serge 711
           movd mm2, ecx
712
           punpcklwd mm2, mm2
713
           movq mm3, qword [m7] ;                  // 0x8000
168 serge 714
 
291 serge 715
           psubw mm3, mm2       ;         // 0x8000 - iconst
716
           punpckldq mm3, mm2
168 serge 717
 
291 serge 718
           pmulhw mm0, mm3
719
           pmullw mm1, mm3
168 serge 720
 
291 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
 
291 serge 730
           add eax, ebx
731
           cmp eax, [r_end]
732
           jb .l1
733
           emms
168 serge 734
 
735
 
291 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
 
291 serge 745
           mov esi, [src]
746
           mov edi, [dest]
747
           mov ecx, [r_size]
748
           shr ecx,8
168 serge 749
@@:
291 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
 
291 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
 
281 serge 774
           mov esi, [src]
775
           mov edi, [dest]
776
           mov ecx, [r_size]
777
           shr ecx, 7
168 serge 778
 
281 serge 779
           movq mm7, [mm80]
780
           movq mm6, [mm_mask]
168 serge 781
@@:
281 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
168 serge 794
           dec ecx
281 serge 795
           jnz @b
168 serge 796
 
281 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
 
281 serge 805
           mov esi, [src]
806
           mov edi, [dest]
807
           mov ecx, [r_size]
808
           shr ecx, 6
168 serge 809
 
281 serge 810
           movq mm7, [mm80]
811
           movq mm6, [mm_mask]
168 serge 812
@@:
281 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
 
281 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
 
281 serge 837
           bsf eax, [mix_buff_map]
838
           jnz .find
839
           xor eax, eax
840
           ret
168 serge 841
.find:
281 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
 
291 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
 
291 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
 
291 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
 
291 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
 
291 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
 
291 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
 
291 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
 
291 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
 
291 serge 908
           ret
168 serge 909
endp
910
 
911
align 4
912
proc s8_s_mmx
913
 
281 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
 
281 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
 
281 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
 
281 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
 
281 serge 954
           ret
168 serge 955
 
956
endp
957
 
958
align 4
959
proc m8_s_mmx
960
 
281 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
 
281 serge 972
           movq mm3, mm1
973
           punpcklwd mm1, mm1
974
           punpckhwd mm3, mm3
168 serge 975
 
281 serge 976
           movq    [edi], mm0
977
           movq    [edi+8], mm2
978
           movq    [edi+16], mm1
979
           movq    [edi+24], mm3
168 serge 980
 
281 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
 
281 serge 992
           movq mm3, mm1
993
           punpcklwd mm1, mm1
994
           punpckhwd mm3, mm3
168 serge 995
 
281 serge 996
           movq    [edi+32], mm0
997
           movq    [edi+40], mm2
998
           movq    [edi+48], mm1
999
           movq    [edi+56], mm3
168 serge 1000
 
281 serge 1001
           ret
168 serge 1002
endp
1003
 
1004
align 4
1005
proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword
1006
 
281 serge 1007
           mov edi, [output]
293 serge 1008
           mov eax, [str0]
1009
           mov ebx, [str1]
1010
           mov esi, 128
1011
           call [mix_2_core]   ;edi, eax, ebx
168 serge 1012
 
293 serge 1013
           add edi, esi
1014
           add eax, esi
1015
           add ebx, esi
1016
           call [mix_2_core]   ;edi, eax, ebx
168 serge 1017
 
293 serge 1018
           add edi, esi
1019
           add eax, esi
1020
           add ebx, esi
1021
           call [mix_2_core]   ;edi, eax, ebx
1022
 
1023
           add edi, esi
1024
           add eax, esi
1025
           add ebx, esi
1026
           call [mix_2_core]   ;edi, eax, ebx
281 serge 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
 
291 serge 1033
           mov edi, [output]
293 serge 1034
           mov eax, [str0]
1035
           mov ebx, [str1]
1036
           mov ecx, [str2]
1037
           mov esi, 128
1038
           call [mix_3_core]
168 serge 1039
 
293 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
 
293 serge 1046
           add edi, esi
1047
           add eax, esi
1048
           add ebx, esi
1049
           add ecx, esi
1050
           call [mix_3_core]
1051
 
1052
           add edi, esi
1053
           add eax, esi
1054
           add ebx, esi
1055
           add ecx, esi
1056
           call [mix_3_core]
291 serge 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
 
291 serge 1066
           call alloc_mix_buff
1067
           and eax, eax
1068
           jz .err
168 serge 1069
 
378 serge 1070
           mov [output], eax
1071
 
291 serge 1072
           mov edi, eax
293 serge 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
 
293 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
1086
 
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
1093
 
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
291 serge 1100
           mov eax, [output]
1101
           ret
168 serge 1102
.err:
291 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
 
291 serge 1112
           mov edi, [output]
168 serge 1113
 
281 serge 1114
           mov eax, [str0]
1115
           mov ebx, [str1]
1116
           mov ecx, [str2]
293 serge 1117
           mov edx, [str3]
1118
           mov esi, 128
1119
           call [mix_4_core]  ;edi, eax, ebx, ecx, edx
168 serge 1120
 
293 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
 
293 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
 
293 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
281 serge 1141
           ret
168 serge 1142
endp
1143
 
1144
align 4
1145
proc copy_mem stdcall, output:dword, input:dword
1146
 
291 serge 1147
           mov edi, [output]
1148
           mov esi, [input]
1149
           mov ecx, 0x80
168 serge 1150
.l1:
291 serge 1151
           mov eax, [esi]
1152
           mov [edi], eax
1153
           add esi, 4
1154
           add edi, 4
1155
           loop .l1
168 serge 1156
 
291 serge 1157
           ret
168 serge 1158
endp
1159
 
1160
proc memcpy
1161
@@:
291 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
 
1185
           call prepare_playlist
1186
 
1187
           cmp [play_count], 0
1188
           je .exit
1189
           call FpuSave
1190
           mov [main_count], 32;
1191
.l00:
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
1199
.l0:
1200
           mov ecx, 4
1201
.l1:
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
1206
 
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
1214
 
1215
           dec ecx
1216
           jnz .l1
1217
 
1218
           cmp [mixCounter], 4
1219
           jnz .m2
1220
 
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
1227
 
1228
           cmp [inputCount], 0
1229
           jnz .l0
1230
.m2:
1231
           cmp [mixIndex], 1
1232
           jne @f
1233
           stdcall copy_mem, [output], [mix_input]
1234
           jmp .m3
1235
@@:
1236
           cmp [mixIndex], 2
1237
           jne @f
1238
           stdcall mix_2_1, [output], [mix_input], [mix_input+4]
1239
           jmp .m3
1240
@@:
1241
           cmp [mixIndex], 3
1242
           jne @f
1243
           stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8]
1244
           jmp .m3
1245
@@:
1246
           stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12]
1247
.m3:
1248
           add [output],512
1249
 
1250
           dec [main_count]
1251
           jnz .l00
1252
 
1253
           call update_stream
1254
           emms
1255
           call FpuRestore
1256
           ret
1257
.exit:
1258
           mov edi, [output]
1259
           mov ecx, 0x1000
1260
           xor eax, eax
1261
           cld
1262
           rep stosd
1263
           ret
1264
endp
1265
 
1266
end if