Subversion Repositories Kolibri OS

Rev

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