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
 
694 serge 8
; Serge 2006-2008
9
; email: infinity_sound@mail.ru
168 serge 10
 
11
format MS COFF
12
 
802 serge 13
DEBUG             equ 1
465 serge 14
 
802 serge 15
 
16
include 'proc32.inc'
17
include 'main.inc'
18
include 'imports.inc'
19
 
20
 
574 serge 21
CURRENT_API     equ   0x0101      ;1.01
22
COMPATIBLE_API  equ   0x0100      ;1.00
465 serge 23
 
574 serge 24
API_VERSION     equ   (COMPATIBLE_API shl 16) or CURRENT_API
25
SOUND_VERSION   equ   CURRENT_API
26
 
27
 
378 serge 28
FORCE_MMX         equ 0  ;set to 1 to force use mmx or
29
FORCE_MMX_128     equ 0  ;integer sse2 extensions
694 serge 30
                         ;and reduce driver size
31
 
378 serge 32
;USE_SSE          equ 0
168 serge 33
 
694 serge 34
USE_SSE2_MIXER    equ 0  ;floating point mixer. Disabled by default
35
 
465 serge 36
OS_BASE           equ 0x80000000
168 serge 37
 
378 serge 38
CAPS_SSE2         equ 26
39
PG_SW             equ 0x003
293 serge 40
 
188 serge 41
public START
168 serge 42
public service_proc
227 serge 43
public version
168 serge 44
 
378 serge 45
RT_INP_EMPTY      equ 0xFF000001
46
RT_OUT_EMPTY      equ 0xFF000002
47
RT_INP_FULL       equ 0xFF000003
48
RT_OUT_FULL       equ 0xFF000004
168 serge 49
 
378 serge 50
EVENT_WATCHED     equ 0x10000000
51
EVENT_SIGNALED    equ 0x20000000
52
MANUAL_RESET      equ 0x40000000
53
MANUAL_DESTROY    equ 0x80000000
168 serge 54
 
378 serge 55
DEV_PLAY          equ 1
56
DEV_STOP          equ 2
57
DEV_CALLBACK      equ 3
58
 
168 serge 59
struc IOCTL
378 serge 60
{  .handle        dd ?
61
   .io_code       dd ?
62
   .input         dd ?
63
   .inp_size      dd ?
64
   .output        dd ?
65
   .out_size      dd ?
168 serge 66
}
67
 
68
virtual at 0
69
  IOCTL IOCTL
70
end virtual
71
 
188 serge 72
section '.flat' code readable align 16
168 serge 73
 
214 serge 74
proc START stdcall, state:dword
75
 
227 serge 76
           cmp [state], 1
77
           jne .exit
78
 
188 serge 79
           stdcall GetService, szSound
168 serge 80
           test eax, eax
81
           jz .fail
82
           mov [hSound], eax
83
 
188 serge 84
           stdcall KernelAlloc, 16*512
168 serge 85
           test eax, eax
86
           jz .out_of_mem
87
           mov [mix_buff], eax
88
 
291 serge 89
           mov eax, str.fd-FD_OFFSET
90
           mov [str.fd], eax
91
           mov [str.bk], eax
168 serge 92
 
293 serge 93
if FORCE_MMX
94
 if FORCE_MMX_128
95
  display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
96
  stop
97
 end if
98
           mov [mix_2_core], mmx_mix_2
99
           mov [mix_3_core], mmx_mix_3
100
           mov [mix_4_core], mmx_mix_4
101
end if
102
 
103
if FORCE_MMX_128
104
 if FORCE_MMX
105
  display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
106
  stop
107
 end if
108
           mov [mix_2_core], mmx128_mix_2
109
           mov [mix_3_core], mmx128_mix_3
110
           mov [mix_4_core], mmx128_mix_4
111
end if
112
 
378 serge 113
if 0
114
 
293 serge 115
if ~(FORCE_MMX or FORCE_MMX_128)  ;autodetect
116
           mov eax, 1
117
           cpuid
118
           bt edx, CAPS_SSE2
119
           jc .mmx128
120
                                           ;old 64-bit mmx
121
           mov [mix_2_core], mmx_mix_2
122
           mov [mix_3_core], mmx_mix_3
123
           mov [mix_4_core], mmx_mix_4
124
           jmp @F
328 serge 125
.mmx128:                                   ;128-bit integer sse2 extensions
293 serge 126
           mov [mix_2_core], mmx128_mix_2
127
           mov [mix_3_core], mmx128_mix_3
128
           mov [mix_4_core], mmx128_mix_4
129
@@:
130
end if
378 serge 131
 
132
end if
168 serge 133
           stdcall set_handler, [hSound], new_mix
378 serge 134
           mov [eng_state], SND_STOP
188 serge 135
           stdcall RegService, szInfinity, service_proc
227 serge 136
           ret
168 serge 137
.fail:
138
     if DEBUG
227 serge 139
           mov esi, msgFail
188 serge 140
           call SysMsgBoardStr
168 serge 141
     end if
214 serge 142
.exit:
227 serge 143
           xor eax, eax
144
           ret
168 serge 145
 
146
.out_of_mem:
147
     if DEBUG
148
           mov esi, msgMem
188 serge 149
           call SysMsgBoardStr
168 serge 150
     end if
227 serge 151
           xor eax, eax
188 serge 152
           ret
214 serge 153
endp
168 serge 154
 
155
handle     equ  IOCTL.handle
156
io_code    equ  IOCTL.io_code
157
input      equ  IOCTL.input
158
inp_size   equ  IOCTL.inp_size
159
output     equ  IOCTL.output
160
out_size   equ  IOCTL.out_size
161
 
1689 art_zh 162
 
163
 
168 serge 164
align 4
1689 art_zh 165
 
166
srv_calls  dd service_proc.srv_getversion       ; 0
167
           dd service_proc.snd_create_buff      ; 1
168
           dd service_proc.snd_destroy_buff     ; 2
169
           dd service_proc.snd_setformat        ; 3
170
           dd service_proc.snd_getformat        ; 4
171
           dd service_proc.snd_reset            ; 5
172
           dd service_proc.snd_setpos           ; 6
173
           dd service_proc.snd_getpos           ; 7
174
           dd service_proc.snd_setbuff          ; 8
175
           dd service_proc.snd_out              ; 9
176
           dd service_proc.snd_play             ; 10
177
           dd service_proc.snd_stop             ; 11
178
           dd service_proc.snd_setvolume        ; 12
179
           dd service_proc.snd_getvolume        ; 13
180
           dd service_proc.snd_setpan           ; 14
181
           dd service_proc.snd_getpan           ; 15
182
           dd service_proc.snd_getbuffsize      ; 16
183
           dd service_proc.snd_getfreespace     ; 17
184
           dd service_proc.snd_settimebase      ; 18
185
           dd service_proc.snd_gettimestamp     ; 19
186
srv_calls_end:
187
 
168 serge 188
proc service_proc stdcall, ioctl:dword
189
 
190
           mov edi, [ioctl]
191
           mov eax, [edi+io_code]
192
 
1689 art_zh 193
           cmp eax, (srv_calls_end-srv_calls)/4
194
           ja  .fail
195
 
196
           cmp eax, SND_CREATE_BUFF
197
           ja @F
198
 
199
           jmp [srv_calls+eax*4]
200
@@:
201
           mov ebx, [edi+input]
202
           mov edx, [ebx]
203
 
204
           cmp [edx+STREAM.magic], 'WAVE'
205
           jne .fail
206
 
207
           cmp [edx+STREAM.size], STREAM.sizeof
208
           jne .fail
209
 
210
           jmp [srv_calls+eax*4]
211
.fail:
212
           mov eax, -1
213
           ret
214
 
215
align 4
216
.srv_getversion:
378 serge 217
           mov eax, [edi+output]
465 serge 218
           cmp [edi+out_size], 4
219
           jne .fail
378 serge 220
           mov eax, [eax]
574 serge 221
           mov [eax], dword API_VERSION
378 serge 222
           xor eax, eax
223
           ret
1689 art_zh 224
 
225
align 4
226
.snd_create_buff:
168 serge 227
           mov ebx, [edi+input]
378 serge 228
           stdcall CreateBuffer,[ebx],[ebx+4]
561 serge 229
           mov edi, [ioctl]
378 serge 230
           mov ecx, [edi+output]
231
           mov ecx, [ecx]
465 serge 232
           mov [ecx], ebx
227 serge 233
           ret
378 serge 234
 
1689 art_zh 235
align 4
236
.snd_destroy_buff:
378 serge 237
           mov eax, edx
1689 art_zh 238
           call DestroyBuffer
227 serge 239
           ret
1689 art_zh 240
 
241
align 4
242
.snd_setformat:
243
           stdcall SetFormat, edx,[ebx+4]
378 serge 244
           ret
168 serge 245
 
1689 art_zh 246
align 4
247
.snd_getformat:
378 serge 248
           movzx eax, word [edx+STREAM.format]
249
           mov ecx, [edi+output]
250
           mov ecx, [ecx]
465 serge 251
           mov [ecx], eax
378 serge 252
           xor eax, eax
227 serge 253
           ret
1689 art_zh 254
 
255
align 4
256
.snd_reset:
572 serge 257
           stdcall ResetBuffer,edx,[ebx+4]
378 serge 258
           ret
1689 art_zh 259
 
260
align 4
261
.snd_setpos:
572 serge 262
           stdcall SetBufferPos,edx,[ebx+4]
378 serge 263
           ret
1689 art_zh 264
 
265
align 4
266
.snd_getpos:
572 serge 267
           stdcall GetBufferPos, edx
561 serge 268
           mov edi, [ioctl]
378 serge 269
           mov ecx, [edi+output]
270
           mov ecx, [ecx]
465 serge 271
           mov [ecx], ebx
378 serge 272
           ret
1689 art_zh 273
 
274
align 4
275
.snd_setbuff:
227 serge 276
           mov eax, [ebx+4]
572 serge 277
           stdcall set_buffer, edx,eax,[ebx+8],[ebx+12]
227 serge 278
           ret
1689 art_zh 279
 
280
align 4
281
.snd_out:
282
           mov eax, [ebx+4]
283
           stdcall wave_out, edx,eax,[ebx+8]
284
           ret
285
 
286
align 4
287
.snd_play:
288
           stdcall play_buffer, edx,[ebx+4]
289
           ret
290
 
291
align 4
292
.snd_stop:
293
           stdcall stop_buffer, edx
294
           ret
295
 
296
align 4
297
.snd_setvolume:
572 serge 298
           stdcall SetBufferVol,edx,[ebx+4],[ebx+8]
378 serge 299
           ret
168 serge 300
 
1689 art_zh 301
align 4
302
.snd_getvolume:
378 serge 303
           mov eax, [edi+output]
304
           mov ecx, [eax]
305
           mov eax, [eax+4]
572 serge 306
           stdcall GetBufferVol,edx,ecx,eax
227 serge 307
           ret
1689 art_zh 308
align 4
309
.snd_setpan:
572 serge 310
           stdcall SetBufferPan,edx,[ebx+4]
378 serge 311
           ret
1689 art_zh 312
 
313
align 4
314
.snd_getpan:
378 serge 315
           mov eax, [edx+STREAM.pan]
316
           mov ebx, [edi+output]
317
           mov ebx, [ebx]
465 serge 318
           mov [ebx], eax
227 serge 319
           xor eax, eax
320
           ret
378 serge 321
 
1689 art_zh 322
align 4
323
.snd_getbuffsize:
378 serge 324
           mov eax, [edx+STREAM.in_size]
325
           mov ecx, [edi+output]
326
           mov ecx, [ecx]
465 serge 327
           mov [ecx], eax
378 serge 328
           xor eax, eax
329
           ret
572 serge 330
 
1689 art_zh 331
align 4
332
.snd_getfreespace:
572 serge 333
           test [edx+STREAM.format], PCM_OUT
334
           jz .fail
335
 
336
           mov ebx, [edx+STREAM.in_free]
337
           mov ecx, [edi+output]
338
           mov [ecx], ebx
339
           xor eax, eax
340
           ret
1689 art_zh 341
align 4
342
.snd_settimebase:
343
           cmp [edi+inp_size], 8
344
           jne .fail
345
 
346
           mov edi, [edi+input]
347
           mov eax, [edi]
348
           mov ebx, [edi+4]
349
           mov dword [edx+STREAM.time_base], eax
350
           mov dword [edx+STREAM.time_base+4], ebx
351
           xor eax, eax
378 serge 352
           ret
1689 art_zh 353
 
354
.snd_gettimestamp:
355
           cmp [edi+out_size], 8
356
           jne .fail
357
 
358
           mov edi, [edi+output]
359
 
360
           push 48
361
           emms
362
           fild  qword [edx+STREAM.time_stamp]
363
           fidiv dword [esp]
364
           fadd  qword [edx+STREAM.time_base]
365
           fstp  qword [edi]
366
           add esp, 4
367
 
368
           xor eax, eax
369
           ret
168 serge 370
endp
371
 
1689 art_zh 372
 
168 serge 373
restore   handle
374
restore   io_code
375
restore   input
376
restore   inp_size
377
restore   output
378
restore   out_size
379
 
328 serge 380
align 4
378 serge 381
proc CreateBuffer stdcall, format:dword, size:dword
227 serge 382
           locals
378 serge 383
             str         dd ?
384
             ring_size   dd ?
385
             ring_pages  dd ?
227 serge 386
           endl
168 serge 387
 
378 serge 388
           mov eax, [format]
389
           cmp ax, PCM_1_8_8
390
           ja .fail
391
 
392
           test eax, PCM_OUT
393
           jnz .test_out
394
           test eax, PCM_RING
395
           jnz .test_ring
396
;staic
567 serge 397
           test eax, PCM_STATIC
568 serge 398
           jz .test_out                   ;use PCM_OUT as default format
378 serge 399
           jmp .test_ok
400
.test_out:
401
           test eax, PCM_RING+PCM_STATIC
402
           jnz .fail
568 serge 403
           or [format], PCM_OUT           ;force set
378 serge 404
           jmp .test_ok
405
.test_ring:
406
           test eax, PCM_OUT+PCM_STATIC
407
           jnz .fail
408
.test_ok:
520 serge 409
 
410
           call GetPid
411
           mov ebx, eax
1689 art_zh 412
           mov eax, STREAM.sizeof
291 serge 413
 
414
           call CreateObject
415
           test eax, eax
227 serge 416
           jz .fail
417
           mov [str], eax
168 serge 418
 
378 serge 419
           mov ebx, [format]
420
           mov [eax+STREAM.format], ebx
168 serge 421
 
378 serge 422
           xor ecx, ecx
423
           movzx ebx, bx
424
           cmp ebx, 19
425
           jb @f
426
           mov ecx, 0x80808080
427
@@:
428
           mov [eax+STREAM.r_silence], ecx
168 serge 429
 
378 serge 430
           shl ebx, 2
431
           lea ebx, [ebx+ebx*2]     ;ebx*=12
168 serge 432
 
378 serge 433
           mov ecx, [resampler_params+ebx]
434
           mov edx, [resampler_params+ebx+4]
435
           mov esi, [resampler_params+ebx+8]
436
 
437
           mov [eax+STREAM.r_size],ecx
438
           mov [eax+STREAM.r_dt],  edx
439
           mov [eax+STREAM.resample], esi
440
           xor ecx, ecx
441
           mov [eax+STREAM.l_vol], ecx
442
           mov [eax+STREAM.r_vol], ecx
443
           mov dword [eax+STREAM.l_amp], 0x7FFF7FFF
444
           mov [eax+STREAM.pan], ecx
445
 
446
           test [format], PCM_STATIC
447
           jnz .static
448
 
449
; ring and waveout
450
 
465 serge 451
           mov ebx, 0x10000
378 serge 452
           test [format], PCM_RING
453
           jz .waveout
454
 
465 serge 455
           mov ebx, [eax+STREAM.r_size]
456
           add ebx, 4095
457
           and ebx, -4096
458
           add ebx, ebx
378 serge 459
.waveout:
465 serge 460
           mov [ring_size], ebx
461
           mov eax, ebx
378 serge 462
           shr ebx, 12
463
           mov [ring_pages], ebx
464
 
520 serge 465
           stdcall CreateRingBuffer, eax, PG_SW
466
 
227 serge 467
           mov edi, [str]
378 serge 468
           mov ecx, [ring_size]
469
           mov [edi+STREAM.in_base], eax
470
           mov [edi+STREAM.in_size], ecx
471
           add eax, 128
472
           mov [edi+STREAM.in_wp], eax
473
           mov [edi+STREAM.in_rp], eax
474
           mov [edi+STREAM.in_count], 0
168 serge 475
 
378 serge 476
           mov [edi+STREAM.in_free], ecx
477
           add eax, ecx
478
           mov [edi+STREAM.in_top], eax
328 serge 479
 
378 serge 480
           jmp .out_buff
481
.static:
482
           mov ecx, [size]
483
           add ecx, 128          ;resampler required
484
           mov [eax+STREAM.in_size], ecx
485
           stdcall KernelAlloc, ecx
486
 
487
           mov edi, [str]
488
           mov [edi+STREAM.in_base], eax
489
           add eax, 128
490
           mov [edi+STREAM.in_wp], eax
491
           mov [edi+STREAM.in_rp], eax
492
           mov ebx, [size]
493
           mov [edi+STREAM.in_count], ebx
494
           mov [edi+STREAM.in_free], ebx
495
           add eax, ebx
496
           mov [edi+STREAM.in_top], eax
497
 
498
.out_buff:
328 serge 499
           stdcall AllocKernelSpace, dword 128*1024
500
 
501
           mov edi, [str]
1689 art_zh 502
           xor ebx, ebx
503
 
378 serge 504
           mov [edi+STREAM.out_base], eax
505
           mov [edi+STREAM.out_wp], eax
506
           mov [edi+STREAM.out_rp], eax
1689 art_zh 507
           mov [edi+STREAM.out_count], ebx
328 serge 508
           add eax, 64*1024
378 serge 509
           mov [edi+STREAM.out_top], eax
168 serge 510
 
1689 art_zh 511
           mov dword [edi+STREAM.time_base],   ebx
512
           mov dword [edi+STREAM.time_base+4], ebx
513
 
514
           mov dword [edi+STREAM.time_stamp],   ebx
515
           mov dword [edi+STREAM.time_stamp+4], ebx
516
 
328 serge 517
           stdcall AllocPages, dword 64/4
518
           mov edi, [str]
378 serge 519
           mov ebx, [edi+STREAM.out_base]
328 serge 520
           mov ecx, 16
521
           or eax, PG_SW
522
           push eax
523
           push ebx
524
           call CommitPages ;eax, ebx, ecx
525
           mov ecx, 16
526
           pop ebx
527
           pop eax
528
           add ebx, 64*1024
529
           call CommitPages    ;double mapped
530
 
531
           mov edi, [str]
378 serge 532
           mov ecx, [edi+STREAM.in_top]
533
           mov edi, [edi+STREAM.in_base]
534
           sub ecx, edi
227 serge 535
           xor eax, eax
378 serge 536
           shr ecx, 2
328 serge 537
           cld
227 serge 538
           rep stosd
168 serge 539
 
328 serge 540
           mov edi, [str]
378 serge 541
           mov edi, [edi+STREAM.out_base]
328 serge 542
           mov ecx, (64*1024)/4
543
           rep stosd
544
 
1058 Galkov 545
           xor esi, esi
546
           mov ecx, MANUAL_DESTROY
378 serge 547
           call CreateEvent
548
 
549
           mov ebx, [str]
550
           mov [ebx+STREAM.notify_event], eax
551
           mov [ebx+STREAM.notify_id], edx
552
 
553
           mov [ebx+STREAM.magic], 'WAVE'
554
           mov [ebx+STREAM.destroy], DestroyBuffer.destroy
1689 art_zh 555
           mov [ebx+STREAM.size], STREAM.sizeof
378 serge 556
           mov [ebx+STREAM.flags], SND_STOP
557
 
558
           pushf
559
           cli
560
           mov eax, str.fd-FD_OFFSET
561
           mov edx, [eax+STREAM.str_fd]
562
           mov [ebx+STREAM.str_fd], edx
563
           mov [ebx+STREAM.str_bk], eax
564
           mov [eax+STREAM.str_fd], ebx
565
           mov [edx+STREAM.str_bk], ebx
566
           popf
567
 
568
           xor eax, eax
227 serge 569
           ret
168 serge 570
.fail:
378 serge 571
           xor ebx, ebx
572
           or eax, -1
227 serge 573
           ret
168 serge 574
endp
575
 
291 serge 576
;param
577
; eax= buffer handle
578
 
168 serge 579
align 4
291 serge 580
DestroyBuffer:
328 serge 581
           .handle  equ esp       ;local
168 serge 582
 
378 serge 583
           mov [eax+STREAM.flags], SND_STOP
291 serge 584
.destroy:
328 serge 585
           push eax
586
 
378 serge 587
           pushfd
291 serge 588
           cli
589
           mov ebx, [eax+STREAM.str_fd]
590
           mov ecx, [eax+STREAM.str_bk]
591
           mov [ebx+STREAM.str_bk], ecx
592
           mov [ecx+STREAM.str_fd], ebx
593
           popf
168 serge 594
 
378 serge 595
           stdcall KernelFree, [eax+STREAM.in_base]
328 serge 596
           mov eax, [.handle]
378 serge 597
           stdcall KernelFree, [eax+STREAM.out_base]
328 serge 598
 
599
           pop eax               ;restore stack
378 serge 600
           call DestroyObject    ;eax= stream
601
           xor eax, eax
602
           ret
168 serge 603
.fail:
378 serge 604
           or eax, -1
227 serge 605
           ret
378 serge 606
restore .handle
168 serge 607
 
608
align 4
378 serge 609
proc SetFormat stdcall, str:dword, format:dword
168 serge 610
 
378 serge 611
           cmp word [format], PCM_1_8_8
612
           ja .fail
168 serge 613
 
378 serge 614
           mov edx, [str]
615
           mov [edx+STREAM.flags], SND_STOP
168 serge 616
 
378 serge 617
           test [edx+STREAM.format], PCM_RING
618
           jnz .fail
168 serge 619
 
378 serge 620
;           mov eax,[edx+STREAM.out_base]
621
;           mov [edx+STREAM.out_wp], eax
622
;           mov [edx+STREAM.out_rp], eax
623
;           mov [edx+STREAM.out_count], 0
168 serge 624
 
378 serge 625
           movzx eax, word [format]
626
           mov word [edx+STREAM.format], ax
627
 
628
           xor ebx, ebx
629
           cmp eax, 19
630
           jb @f
631
           mov ebx, 0x80808080
168 serge 632
@@:
378 serge 633
           mov [edx+STREAM.r_silence], ebx
168 serge 634
 
378 serge 635
           shl eax, 2
636
           lea eax, [eax+eax*2]     ;eax*=12
168 serge 637
 
378 serge 638
           mov edi, [resampler_params+eax]
639
           mov ecx, [resampler_params+eax+4]
640
           mov ebx, [resampler_params+eax+8]
168 serge 641
 
378 serge 642
           mov [edx+STREAM.r_size],edi
643
           mov [edx+STREAM.r_dt],  ecx
644
           mov [edx+STREAM.resample], ebx
168 serge 645
 
378 serge 646
           mov edi, [edx+STREAM.in_base]
647
           mov ecx, 128/4
648
           mov eax, [edx+STREAM.r_silence]
285 serge 649
           cld
650
           rep stosd
227 serge 651
           xor eax, eax
652
           ret
168 serge 653
.fail:
378 serge 654
           or eax, -1
227 serge 655
           ret
168 serge 656
endp
657
 
378 serge 658
; for static buffers only
659
; use waveout for streams
660
 
168 serge 661
align 4
378 serge 662
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
168 serge 663
 
378 serge 664
           mov edx, [str]
665
           test [edx+STREAM.format], PCM_OUT
666
           jnz .fail
168 serge 667
 
378 serge 668
           mov esi, [src]
669
           mov edi, [offs]
670
           add edi, [edx+STREAM.in_base]
671
           add edi, 128
168 serge 672
 
378 serge 673
           cmp edi, [edx+STREAM.in_top]
674
           jae .fail
168 serge 675
 
378 serge 676
           mov ecx, [size]
677
           lea ebx, [ecx+edi]
678
           sub ebx, [edx+STREAM.in_top]
679
           jb @F
680
           sub ecx, ebx
681
@@:
682
           shr ecx, 2
683
           cld
684
           rep movsd
685
           xor eax,eax
227 serge 686
           ret
168 serge 687
.fail:
378 serge 688
           or eax, -1
227 serge 689
           ret
168 serge 690
endp
691
 
378 serge 692
; for stream buffers only
693
 
168 serge 694
align 4
378 serge 695
proc wave_out stdcall, str:dword,src:dword,size:dword
696
           locals
697
             state_saved  dd ?
698
             fpu_state    rb 528
699
           endl
168 serge 700
 
227 serge 701
           mov edx, [str]
378 serge 702
           mov eax, [edx+STREAM.format]
568 serge 703
           test eax, PCM_OUT
704
           jz .fail
168 serge 705
 
378 serge 706
           cmp ax, PCM_ALL
707
           je .fail
168 serge 708
 
227 serge 709
           mov esi,[src]
710
           test esi, esi
711
           jz .fail
168 serge 712
 
465 serge 713
           cmp esi, OS_BASE
575 serge 714
           jae .fail
168 serge 715
 
378 serge 716
           mov [state_saved], 0
168 serge 717
 
378 serge 718
.main_loop:
719
           mov edx, [str]
168 serge 720
 
378 serge 721
           mov ebx, [size]
722
           test ebx, ebx
723
           jz .done
724
 
725
           cmp [edx+STREAM.flags], SND_STOP
726
           jne .fill
727
 
728
           mov edi, [edx+STREAM.in_base]
729
           mov ecx, 128/4
730
           mov eax, [edx+STREAM.r_silence]
731
           cld
732
           rep stosd
733
 
734
           mov ecx, [edx+STREAM.in_size]
735
           sub ecx, 128
736
           mov [edx+STREAM.in_wp], edi
737
           mov [edx+STREAM.in_rp], edi
738
           mov [edx+STREAM.in_count], 0
739
           mov [edx+STREAM.in_free], ecx
740
 
741
           mov eax,[edx+STREAM.out_base]
742
           mov [edx+STREAM.out_wp], eax
743
           mov [edx+STREAM.out_rp], eax
744
           mov [edx+STREAM.out_count], 0
745
.fill:
1024 serge 746
           cli
747
 
378 serge 748
           mov ecx, [edx+STREAM.in_free]
749
           test ecx, ecx
750
           jz .wait
751
 
752
           cmp ecx, ebx
753
           jbe @F
754
 
755
           mov ecx, ebx
756
@@:
285 serge 757
           sub [size], ecx
378 serge 758
           add [edx+STREAM.in_count], ecx
759
           sub [edx+STREAM.in_free], ecx
168 serge 760
 
285 serge 761
           shr ecx, 2
378 serge 762
           mov edi, [edx+STREAM.in_wp]
763
           mov esi, [src]
285 serge 764
           cld
765
           rep movsd
378 serge 766
 
767
           mov [src], esi
768
           cmp edi, [edx+STREAM.in_top]
769
           jb @F
770
           sub edi, [edx+STREAM.in_size]
285 serge 771
@@:
378 serge 772
           mov [edx+STREAM.in_wp], edi
168 serge 773
 
378 serge 774
           cmp [edx+STREAM.out_count], 32768
775
           jae .skip
776
 
777
           cmp [state_saved], 0
778
           jne @F
779
           lea eax, [fpu_state+15]
780
           and eax, -16
781
           call FpuSave
782
           mov [state_saved], 1
783
@@:
784
           stdcall refill, edx
1024 serge 785
 
378 serge 786
.skip:
1024 serge 787
           sti
575 serge 788
           mov edx, [str]
789
           mov [edx+STREAM.flags], SND_PLAY
378 serge 790
           cmp [eng_state], SND_PLAY
791
           je .main_loop
792
 
793
           stdcall dev_play, [hSound]
794
           mov [eng_state], SND_PLAY
795
           jmp .main_loop
796
.wait:
1024 serge 797
           sti
378 serge 798
           mov edx, [str]
799
           mov eax, [edx+STREAM.notify_event]
800
           mov ebx, [edx+STREAM.notify_id]
801
           call WaitEvent   ;eax ebx
802
           jmp .main_loop
285 serge 803
.done:
378 serge 804
           cmp [state_saved], 1
805
           jne @F
806
 
807
           lea eax, [fpu_state+15]
808
           and eax, -16
809
           call FpuRestore
810
@@:
227 serge 811
           xor eax, eax
378 serge 812
           ret
813
.fail:
814
           or eax, -1
815
           ret
816
endp
817
 
818
; both static and stream
819
; reset all but not clear buffers
820
 
821
 
822
; flags reserved
823
;  RESET_INPUT  equ 1   ;reserved reset and clear input buffer
824
;  RESET_OUTPUT equ 2   ;reserved reset and clear output buffer
825
;  RESET_ALL    equ 3
826
 
827
 
828
align 4
829
proc ResetBuffer stdcall, str:dword, flags:dword
830
 
831
           mov edx, [str]
832
           mov [edx+STREAM.flags], SND_STOP
833
 
834
           mov edi, [edx+STREAM.in_base]
835
           mov ecx, 128/4
836
           mov eax, [edx+STREAM.r_silence]
837
           cld
838
           rep stosd
839
 
840
           mov [edx+STREAM.in_wp], edi
841
           mov [edx+STREAM.in_rp], edi
842
 
567 serge 843
           test [edx+STREAM.flags], PCM_STATIC
844
           jnz .static
378 serge 845
           mov [edx+STREAM.in_count], 0
567 serge 846
           jmp @F
847
.static:
378 serge 848
           mov eax, [edx+STREAM.in_size]
567 serge 849
           mov [edx+STREAM.in_count], eax
850
@@:
851
 
852
           mov eax, [edx+STREAM.in_size]
378 serge 853
           sub eax, 128
854
           mov [edx+STREAM.in_free], eax
855
 
856
           xor eax, eax
857
           mov ebx,[edx+STREAM.out_base]
858
           mov [edx+STREAM.out_wp], ebx
859
           mov [edx+STREAM.out_rp], ebx
860
           mov [edx+STREAM.out_count], eax
861
           ret
862
.fail:
863
           or eax, -1
864
           ret
865
endp
866
 
867
; for static buffers only
868
 
869
align 4
870
proc SetBufferPos stdcall, str:dword, pos:dword
871
 
872
           mov edx, [str]
568 serge 873
           test [edx+STREAM.format], PCM_STATIC
874
           jz .fail
378 serge 875
 
876
           mov [edx+STREAM.flags], SND_STOP
877
 
878
           mov eax, [pos]
879
           add eax, [edx+STREAM.in_base]
880
           mov ebx, [edx+STREAM.in_top]
881
           add eax, 128
882
 
883
           cmp eax, ebx
884
           jae .fail
885
 
886
           mov [edx+STREAM.in_rp], eax
887
           sub ebx, eax
888
           mov [edx+STREAM.in_count], ebx
889
           xor eax, eax
890
           ret
891
.fail:
892
           or eax, -1
893
           ret
894
endp
895
 
896
align 4
897
proc GetBufferPos stdcall, str:dword
898
 
899
           mov edx, [str]
568 serge 900
           test [edx+STREAM.format], PCM_STATIC
901
           jz .fail
378 serge 902
 
903
           mov ebx, [edx+STREAM.in_rp]
567 serge 904
           sub ebx, [edx+STREAM.in_base]
905
           sub ebx, 128
378 serge 906
           xor eax, eax
907
           ret
908
.fail:
909
           xor ebx,ebx
910
           or eax, -1
911
           ret
912
endp
913
 
914
; both
915
 
916
align 4
917
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword
918
 
919
           mov edx, [str]
920
           stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan]
921
           ret
922
endp
923
 
924
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword
925
           locals
926
             _600    dd ?
927
             _32767  dd ?
928
             state   rb 108
929
           endl
930
 
931
           mov [_600], 0x44160000   ;600.0
932
           mov [_32767], 32767
933
 
934
           lea ebx, [state]
935
           fnsave [ebx]
936
 
937
           movq mm0, qword [l_vol]
938
           pminsw mm0, qword [vol_max]
939
           pmaxsw mm0, qword [vol_min]
940
           movq qword [l_vol], mm0
941
           movq qword [edx+STREAM.l_vol], mm0
942
 
943
           movd mm1,[pan]
944
           pminsw mm1, qword [pan_max]
945
           pmaxsw mm1, qword [vol_min]
946
           movd [edx+STREAM.pan], mm1
947
 
948
           cmp word [edx+STREAM.pan], 0
949
           jl @F
950
 
951
           psubsw mm0,mm1
952
           pminsw mm0, qword [vol_max]
953
           pmaxsw mm0, qword [vol_min]
954
           movd [l_vol],mm0
955
           jmp .calc_amp
956
@@:
957
           punpckhdq mm0,mm0
958
           paddsw mm0,mm1
959
           pminsw mm0, qword [vol_max]
960
           pmaxsw mm0, qword [vol_min]
961
           movd [r_vol], mm0
962
.calc_amp:
963
           emms
964
           fild word [l_vol]
965
 
966
           call .calc
967
 
968
           fistp word [edx+STREAM.l_amp]
694 serge 969
           fstp dword [edx+STREAM.l_amp_f]
378 serge 970
           fstp st0
971
 
972
           fild word [r_vol]
973
 
974
           call .calc
975
 
976
           fistp word [edx+STREAM.r_amp]
694 serge 977
           fstp dword [edx+STREAM.r_amp_f]
378 serge 978
           fstp st0
979
 
980
           fnclex
981
           lea ebx, [state]
982
           frstor [ebx]
983
 
984
           xor eax, eax
227 serge 985
           inc eax
986
           ret
378 serge 987
.calc:
988
           fdiv dword [_600]
989
           fld st0
990
           frndint
991
           fxch st1
992
           fsub st, st1
993
           f2xm1
994
           fld1
995
           faddp st1, st0
996
           fscale
694 serge 997
           fld st0
378 serge 998
           fimul dword [_32767]
999
           ret 0
1000
endp
1001
 
1002
align 4
1003
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword
1004
 
1005
           mov edx, [str]
1006
           mov eax, [p_lvol]
1007
           movsx ecx, word [edx+STREAM.l_vol]
1008
           mov [eax], ecx
1009
 
1010
           mov eax, [p_rvol]
1011
           movsx ecx, word [edx+STREAM.r_vol]
1012
           mov [eax], ecx
1013
           xor eax, eax
1014
           ret
1015
endp
1016
 
1017
align 4
1018
proc SetBufferPan stdcall, str:dword,pan:dword
1019
 
1020
           mov edx, [str]
1021
           stdcall set_vol_param,[edx+STREAM.l_vol],\
1022
                                 [edx+STREAM.r_vol],[pan]
1023
           ret
1024
endp
1025
 
1026
; for static and ring buffers only
1027
 
1028
align 4
1029
proc play_buffer stdcall, str:dword, flags:dword
1030
 
1031
           mov ebx, [str]
1032
           mov eax, [ebx+STREAM.format]
1033
           test eax, PCM_OUT
1034
           jnz .fail
1035
 
1036
           cmp ax, PCM_ALL
1037
           je .fail
1038
 
1039
           mov [ebx+STREAM.flags], SND_PLAY
1040
           cmp [eng_state], SND_PLAY
1041
           je .done
1042
 
1043
           stdcall  dev_play, [hSound]
1044
           mov [eng_state], SND_PLAY
1045
.done:
1046
           test [flags], PLAY_SYNC
1047
           jz @F
1048
 
1049
           mov edx, [str]
1050
.wait:
1051
           mov eax, [edx+STREAM.notify_event]
1052
           mov ebx, [edx+STREAM.notify_id]
1053
           call WaitEvent   ;eax ebx
1054
 
1055
           mov edx, [str]
1056
           cmp [edx+STREAM.flags], SND_STOP
1057
           jne .wait
1058
@@:
1059
           xor eax, eax
1060
           ret
168 serge 1061
.fail:
378 serge 1062
           or eax, -1
1063
           ret
1064
endp
1065
 
567 serge 1066
; for static and ring buffers only
378 serge 1067
 
1068
align 4
1069
proc stop_buffer stdcall, str:dword
1070
 
1071
           mov edx, [str]
1072
           test [edx+STREAM.format], PCM_STATIC+PCM_RING
1073
           jz .fail
1074
 
1075
           mov [edx+STREAM.flags], SND_STOP
1076
 
1077
;           stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
1078
 
1079
           mov eax, [edx+STREAM.notify_event]
1080
           mov ebx, [edx+STREAM.notify_id]
1081
           call ClearEvent   ;eax ebx
1082
 
227 serge 1083
           xor eax, eax
1084
           ret
378 serge 1085
.fail:
1086
           or eax, -1
1087
           ret
168 serge 1088
endp
1089
 
695 serge 1090
; param
378 serge 1091
;  eax= mix_list
1092
 
168 serge 1093
align 4
378 serge 1094
do_mix_list:
1095
 
1096
           xor edx, edx
1097
           mov esi, str.fd-FD_OFFSET
1098
           mov ebx, [esi+STREAM.str_fd]
1099
@@:
1100
           cmp ebx, esi
1101
           je .done
1102
 
1103
           cmp [ebx+STREAM.magic], 'WAVE'
1104
           jne .next
1105
 
1689 art_zh 1106
           cmp [ebx+STREAM.size], STREAM.sizeof
378 serge 1107
           jne .next
1108
 
1109
           cmp [ebx+STREAM.flags], SND_PLAY;
1110
           jne .next
1111
 
1112
           mov ecx, [ebx+STREAM.out_count]
1113
           test ecx, ecx
1114
           jnz .l1
1115
 
1116
           test [ebx+STREAM.format], PCM_RING
1117
           jnz .next
1118
           mov [ebx+STREAM.flags], SND_STOP
1119
           jmp .next
1120
.l1:
1121
           cmp ecx, 512
1122
           jae .add_buff
1123
 
1124
           mov edi, [ebx+STREAM.out_rp]
1125
           add edi, ecx
1126
           sub ecx, 512
1127
           neg ecx
1128
           push eax
1129
           xor eax, eax
1130
           cld
1131
           rep stosb
1132
           pop eax
1133
 
1134
           mov [ebx+STREAM.out_count], 512
1135
 
1136
.add_buff:
1137
           mov ecx, [ebx+STREAM.out_rp]
1138
           mov [eax],ecx
694 serge 1139
 
1140
if USE_SSE2_MIXER
1141
           mov edi, dword [ebx+STREAM.l_amp_f]
1142
           mov [eax+4], edi
1143
           mov edi, dword [ebx+STREAM.r_amp_f]
1144
           mov [eax+8], edi
1145
else
378 serge 1146
           mov edi, dword [ebx+STREAM.l_amp]
1147
           mov [eax+4], edi
694 serge 1148
end if
378 serge 1149
           add [ebx+STREAM.out_rp], 512
1150
           sub [ebx+STREAM.out_count], 512
1151
 
694 serge 1152
           add eax, 12
378 serge 1153
           inc edx
1154
.next:
1155
           mov ebx, [ebx+STREAM.str_fd]
1156
           jmp @B
1157
.done:
1158
           mov eax, edx
1159
           ret
1160
 
1161
align 4
291 serge 1162
prepare_playlist:
168 serge 1163
 
227 serge 1164
           xor edx, edx
291 serge 1165
           mov [play_count], edx
1166
           mov esi, str.fd-FD_OFFSET
1167
           mov edi, [esi+STREAM.str_fd]
1168
@@:
1169
           cmp edi, esi
1170
           je .done
168 serge 1171
 
291 serge 1172
           cmp [edi+STREAM.magic], 'WAVE'
168 serge 1173
           jne .next
1174
 
1689 art_zh 1175
           cmp [edi+STREAM.size], STREAM.sizeof
168 serge 1176
           jne .next
1177
 
291 serge 1178
           cmp [edi+STREAM.flags], SND_PLAY;
227 serge 1179
           jne .next
168 serge 1180
 
291 serge 1181
           mov [play_list+edx], edi
227 serge 1182
           inc [play_count]
1183
           add edx, 4
168 serge 1184
.next:
291 serge 1185
           mov edi, [edi+STREAM.str_fd]
1186
           jmp @B
1187
.done:
227 serge 1188
           ret
168 serge 1189
 
1190
align 4
1191
proc set_handler stdcall, hsrv:dword, handler_proc:dword
1192
           locals
1193
             handler    dd ?
1194
             io_code    dd ?
1195
             input      dd ?
1196
             inp_size   dd ?
1197
             output     dd ?
1198
             out_size   dd ?
1199
             val        dd ?
1200
           endl
1201
 
1202
           mov eax, [hsrv]
1203
           lea ecx, [handler_proc]
1204
           xor ebx, ebx
1205
 
1206
           mov [handler], eax
1207
           mov [io_code], DEV_CALLBACK
1208
           mov [input], ecx
1209
           mov [inp_size], 4
1210
           mov [output], ebx
1211
           mov [out_size], 0
1212
 
1213
           lea eax, [handler]
188 serge 1214
           stdcall ServiceHandler, eax
168 serge 1215
           ret
1216
endp
1217
 
1218
align 4
1219
proc dev_play stdcall, hsrv:dword
1220
           locals
1221
             handle     dd ?
1222
             io_code    dd ?
1223
             input      dd ?
1224
             inp_size   dd ?
1225
             output     dd ?
1226
             out_size   dd ?
1227
             val        dd ?
1228
           endl
1229
 
1230
           mov eax, [hsrv]
1231
           xor ebx, ebx
1232
 
1233
           mov [handle], eax
1234
           mov [io_code], DEV_PLAY
1235
           mov [input], ebx
1236
           mov [inp_size], ebx
1237
           mov [output], ebx
1238
           mov [out_size], ebx
1239
 
1240
           lea eax, [handle]
188 serge 1241
           stdcall ServiceHandler, eax
168 serge 1242
           ret
1243
endp
1244
 
378 serge 1245
if 0
1246
align 4
1247
dword2str:
1248
      mov  esi, hex_buff
1249
      mov ecx, -8
1250
@@:
1251
      rol eax, 4
1252
      mov ebx, eax
1253
      and ebx, 0x0F
1254
      mov bl, [ebx+hexletters]
1255
      mov [8+esi+ecx], bl
1256
      inc ecx
1257
      jnz @B
1258
      ret
1259
 
1260
hexletters   db '0123456789ABCDEF'
1261
hex_buff     db 8 dup(0),13,10,0
1262
 
1263
end if
1264
 
168 serge 1265
include 'mixer.asm'
293 serge 1266
include 'mix_mmx.inc'
1267
include 'mix_sse2.inc'
168 serge 1268
 
291 serge 1269
;if USE_SSE
1270
; include 'mix_sse.inc'
1271
;end if
1272
 
168 serge 1273
align 16
1274
resampler_params:
378 serge 1275
     ;r_size    r_dt   resampler_func
1276
     dd 0,0,0                                  ; 0  PCM_ALL
1277
     dd 16384,      0, copy_stream    ; 1  PCM_2_16_48
802 serge 1278
     dd  8192,      0, m16_stereo     ; 2  PCM_1_16_48
168 serge 1279
 
378 serge 1280
     dd 16384,  30109, resample_2     ; 3  PCM_2_16_44
1281
     dd  8192,  30109, resample_1     ; 4  PCM_1_16_44
168 serge 1282
 
378 serge 1283
     dd 16384,  21846, resample_2     ; 5  PCM_2_16_32
1284
     dd  8192,  21846, resample_1     ; 6  PCM_1_16_32
168 serge 1285
 
378 serge 1286
     dd 16384,  16384, resample_2     ; 7  PCM_2_16_24
1287
     dd  8192,  16384, resample_1     ; 8  PCM_1_16_24
168 serge 1288
 
378 serge 1289
     dd  8192,  15052, resample_2     ; 9  PCM_2_16_22
1290
     dd  4096,  15052, resample_1     ;10  PCM_1_16_22
168 serge 1291
 
378 serge 1292
     dd  8192,  10923, resample_2     ;11  PCM_2_16_16
1293
     dd  4096,  10923, resample_1     ;12  PCM_1_16_16
168 serge 1294
 
378 serge 1295
     dd  8192,   8192, resample_2     ;13  PCM_2_16_12
1296
     dd  4096,   8192, resample_1     ;14  PCM_1_16_12
168 serge 1297
 
378 serge 1298
     dd  4096,   7527, resample_2     ;15  PCM_2_16_11
1299
     dd  2048,   7527, resample_1     ;16  PCM_1_16_11
168 serge 1300
 
378 serge 1301
     dd  4096,   5462, resample_2     ;17  PCM_2_16_8
1302
     dd  2048,   5462, resample_1     ;18  PCM_1_16_8
168 serge 1303
 
378 serge 1304
     dd 16384,      0, s8_stereo      ;19  PCM_2_8_48
1305
     dd  8192,      0, m8_stereo      ;20  PCM_1_8_48
168 serge 1306
 
378 serge 1307
     dd  8192,  30109, resample_28    ;21  PCM_2_8_44
1308
     dd  4096,  30109, resample_18    ;22  PCM_1_8_44
168 serge 1309
 
378 serge 1310
     dd  8192,  21846, resample_28    ;23  PCM_2_8_32
1311
     dd  4096,  21846, resample_18    ;24  PCM_1_8_32
168 serge 1312
 
378 serge 1313
     dd  8192,  16384, resample_28    ;25  PCM_2_8_24
1314
     dd  4096,  16384, resample_18    ;26  PCM_1_8_24
168 serge 1315
 
378 serge 1316
     dd  4096,  15052, resample_28    ;27  PCM_2_8_22
1317
     dd  2048,  15052, resample_18    ;28  PCM_1_8_22
168 serge 1318
 
378 serge 1319
     dd  4096,  10923, resample_28    ;29  PCM_2_8_16
1320
     dd  2048,  10923, resample_18    ;30  PCM_1_8_16
168 serge 1321
 
378 serge 1322
     dd  4096,   8192, resample_28    ;31  PCM_2_8_12
1323
     dd  2048,   8192, resample_18    ;32  PCM_1_8_12
168 serge 1324
 
378 serge 1325
     dd  2048,   7527, resample_28    ;33  PCM_2_8_11
1326
     dd  1024,   7527, resample_18    ;34  PCM_1_8_11
168 serge 1327
 
378 serge 1328
     dd  2048,   5462, resample_28    ;35  PCM_2_8_8
1329
     dd  1024,   5462, resample_18    ;36  PCM_1_8_8
168 serge 1330
 
281 serge 1331
m7            dw 0x8000,0x8000,0x8000,0x8000
1332
mm80          dq 0x8080808080808080
1333
mm_mask       dq 0xFF00FF00FF00FF00
168 serge 1334
 
378 serge 1335
vol_max       dd 0x00000000,0x00000000
1336
vol_min       dd 0x0000D8F0,0x0000D8F0
1337
pan_max       dd 0x00002710,0x00002710
1338
 
291 serge 1339
;stream_map    dd 0xFFFF       ; 16
574 serge 1340
version       dd (5 shl 16) or SOUND_VERSION
168 serge 1341
 
281 serge 1342
szInfinity    db 'INFINITY',0
1343
szSound       db 'SOUND',0
168 serge 1344
 
1345
if DEBUG
281 serge 1346
msgFail       db 'Sound service not loaded',13,10,0
1347
msgPlay       db 'Play buffer',13,10,0
1348
msgStop       db 'Stop',13,10,0
1349
msgUser       db 'User callback',13,10,0
1350
msgMem        db 'Not enough memory',13,10,0
291 serge 1351
msgDestroy    db 'Destroy sound buffer', 13,10,0
378 serge 1352
msgWaveout    db 'Play waveout', 13,10,0
1353
msgSetVolume  db 'Set volume',13,10,0
168 serge 1354
end if
188 serge 1355
 
1356
section '.data' data readable writable align 16
1357
 
281 serge 1358
play_list     rd 16
1359
mix_input     rd 16
1360
play_count    rd 1
1361
hSound        rd 1
378 serge 1362
eng_state     rd 1
281 serge 1363
mix_buff      rd 1
1364
mix_buff_map  rd 1
291 serge 1365
str.fd        rd 1
1366
str.bk        rd 1
188 serge 1367
 
293 serge 1368
mix_2_core    rd 1
1369
mix_3_core    rd 1
1370
mix_4_core    rd 1