Subversion Repositories Kolibri OS

Rev

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

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