Subversion Repositories Kolibri OS

Rev

Rev 567 | 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
568 serge 325
           jz .test_out                   ;use PCM_OUT as default format
378 serge 326
           jmp .test_ok
327
.test_out:
328
           test eax, PCM_RING+PCM_STATIC
329
           jnz .fail
568 serge 330
           or [format], PCM_OUT           ;force set
378 serge 331
           jmp .test_ok
332
.test_ring:
333
           test eax, PCM_OUT+PCM_STATIC
334
           jnz .fail
335
.test_ok:
520 serge 336
 
337
           call GetPid
338
           mov ebx, eax
291 serge 339
           mov eax, STREAM_SIZE
340
 
341
           call CreateObject
342
           test eax, eax
227 serge 343
           jz .fail
344
           mov [str], eax
168 serge 345
 
378 serge 346
           mov ebx, [format]
347
           mov [eax+STREAM.format], ebx
168 serge 348
 
378 serge 349
           xor ecx, ecx
350
           movzx ebx, bx
351
           cmp ebx, 19
352
           jb @f
353
           mov ecx, 0x80808080
354
@@:
355
           mov [eax+STREAM.r_silence], ecx
168 serge 356
 
378 serge 357
           shl ebx, 2
358
           lea ebx, [ebx+ebx*2]     ;ebx*=12
168 serge 359
 
378 serge 360
           mov ecx, [resampler_params+ebx]
361
           mov edx, [resampler_params+ebx+4]
362
           mov esi, [resampler_params+ebx+8]
363
 
364
           mov [eax+STREAM.r_size],ecx
365
           mov [eax+STREAM.r_dt],  edx
366
           mov [eax+STREAM.resample], esi
367
           xor ecx, ecx
368
           mov [eax+STREAM.l_vol], ecx
369
           mov [eax+STREAM.r_vol], ecx
370
           mov dword [eax+STREAM.l_amp], 0x7FFF7FFF
371
           mov [eax+STREAM.pan], ecx
372
 
373
           test [format], PCM_STATIC
374
           jnz .static
375
 
376
; ring and waveout
377
 
465 serge 378
           mov ebx, 0x10000
378 serge 379
           test [format], PCM_RING
380
           jz .waveout
381
 
465 serge 382
           mov ebx, [eax+STREAM.r_size]
383
           add ebx, 4095
384
           and ebx, -4096
385
           add ebx, ebx
378 serge 386
.waveout:
465 serge 387
           mov [ring_size], ebx
388
           mov eax, ebx
378 serge 389
           shr ebx, 12
390
           mov [ring_pages], ebx
391
 
520 serge 392
           stdcall CreateRingBuffer, eax, PG_SW
393
 
227 serge 394
           mov edi, [str]
378 serge 395
           mov ecx, [ring_size]
396
           mov [edi+STREAM.in_base], eax
397
           mov [edi+STREAM.in_size], ecx
398
           add eax, 128
561 serge 399
        ;   sub ecx, 128
378 serge 400
           mov [edi+STREAM.in_wp], eax
401
           mov [edi+STREAM.in_rp], eax
402
           mov [edi+STREAM.in_count], 0
168 serge 403
 
378 serge 404
           mov [edi+STREAM.in_free], ecx
405
           add eax, ecx
406
           mov [edi+STREAM.in_top], eax
328 serge 407
 
378 serge 408
           jmp .out_buff
409
.static:
410
           mov ecx, [size]
411
           add ecx, 128          ;resampler required
412
           mov [eax+STREAM.in_size], ecx
413
           stdcall KernelAlloc, ecx
414
 
415
           mov edi, [str]
416
           mov [edi+STREAM.in_base], eax
417
           add eax, 128
418
           mov [edi+STREAM.in_wp], eax
419
           mov [edi+STREAM.in_rp], eax
420
           mov ebx, [size]
421
           mov [edi+STREAM.in_count], ebx
422
           mov [edi+STREAM.in_free], ebx
423
           add eax, ebx
424
           mov [edi+STREAM.in_top], eax
425
 
426
.out_buff:
328 serge 427
           stdcall AllocKernelSpace, dword 128*1024
428
 
429
           mov edi, [str]
378 serge 430
           mov [edi+STREAM.out_base], eax
431
           mov [edi+STREAM.out_wp], eax
432
           mov [edi+STREAM.out_rp], eax
433
           mov [edi+STREAM.out_count], 0
328 serge 434
           add eax, 64*1024
378 serge 435
           mov [edi+STREAM.out_top], eax
168 serge 436
 
328 serge 437
           stdcall AllocPages, dword 64/4
438
           mov edi, [str]
378 serge 439
           mov ebx, [edi+STREAM.out_base]
328 serge 440
           mov ecx, 16
441
           or eax, PG_SW
442
           push eax
443
           push ebx
444
           call CommitPages ;eax, ebx, ecx
445
           mov ecx, 16
446
           pop ebx
447
           pop eax
448
           add ebx, 64*1024
449
           call CommitPages    ;double mapped
450
 
451
           mov edi, [str]
378 serge 452
           mov ecx, [edi+STREAM.in_top]
453
           mov edi, [edi+STREAM.in_base]
454
           sub ecx, edi
227 serge 455
           xor eax, eax
378 serge 456
           shr ecx, 2
328 serge 457
           cld
227 serge 458
           rep stosd
168 serge 459
 
328 serge 460
           mov edi, [str]
378 serge 461
           mov edi, [edi+STREAM.out_base]
328 serge 462
           mov ecx, (64*1024)/4
463
           rep stosd
464
 
378 serge 465
           xor edx, edx
466
           mov ebx, MANUAL_DESTROY
467
           call CreateEvent
468
 
469
           mov ebx, [str]
470
           mov [ebx+STREAM.notify_event], eax
471
           mov [ebx+STREAM.notify_id], edx
472
 
473
           mov [ebx+STREAM.magic], 'WAVE'
474
           mov [ebx+STREAM.destroy], DestroyBuffer.destroy
475
           mov [ebx+STREAM.size], STREAM_SIZE
476
           mov [ebx+STREAM.flags], SND_STOP
477
 
478
           pushf
479
           cli
480
           mov eax, str.fd-FD_OFFSET
481
           mov edx, [eax+STREAM.str_fd]
482
           mov [ebx+STREAM.str_fd], edx
483
           mov [ebx+STREAM.str_bk], eax
484
           mov [eax+STREAM.str_fd], ebx
485
           mov [edx+STREAM.str_bk], ebx
486
           popf
487
 
488
           xor eax, eax
227 serge 489
           ret
168 serge 490
.fail:
378 serge 491
           xor ebx, ebx
492
           or eax, -1
227 serge 493
           ret
168 serge 494
endp
495
 
291 serge 496
;param
497
; eax= buffer handle
498
 
168 serge 499
align 4
291 serge 500
DestroyBuffer:
328 serge 501
           .handle  equ esp       ;local
168 serge 502
 
378 serge 503
           mov [eax+STREAM.flags], SND_STOP
291 serge 504
.destroy:
328 serge 505
           push eax
506
 
378 serge 507
           pushfd
291 serge 508
           cli
509
           mov ebx, [eax+STREAM.str_fd]
510
           mov ecx, [eax+STREAM.str_bk]
511
           mov [ebx+STREAM.str_bk], ecx
512
           mov [ecx+STREAM.str_fd], ebx
513
           popf
168 serge 514
 
378 serge 515
           stdcall KernelFree, [eax+STREAM.in_base]
328 serge 516
           mov eax, [.handle]
378 serge 517
           stdcall KernelFree, [eax+STREAM.out_base]
328 serge 518
 
519
           pop eax               ;restore stack
378 serge 520
           call DestroyObject    ;eax= stream
521
           xor eax, eax
522
           ret
168 serge 523
.fail:
378 serge 524
           or eax, -1
227 serge 525
           ret
378 serge 526
restore .handle
168 serge 527
 
528
align 4
378 serge 529
proc SetFormat stdcall, str:dword, format:dword
168 serge 530
 
378 serge 531
           cmp word [format], PCM_1_8_8
532
           ja .fail
168 serge 533
 
378 serge 534
           mov edx, [str]
535
           mov [edx+STREAM.flags], SND_STOP
168 serge 536
 
378 serge 537
           test [edx+STREAM.format], PCM_RING
538
           jnz .fail
168 serge 539
 
378 serge 540
;           mov eax,[edx+STREAM.out_base]
541
;           mov [edx+STREAM.out_wp], eax
542
;           mov [edx+STREAM.out_rp], eax
543
;           mov [edx+STREAM.out_count], 0
168 serge 544
 
378 serge 545
           movzx eax, word [format]
546
           mov word [edx+STREAM.format], ax
547
 
548
           xor ebx, ebx
549
           cmp eax, 19
550
           jb @f
551
           mov ebx, 0x80808080
168 serge 552
@@:
378 serge 553
           mov [edx+STREAM.r_silence], ebx
168 serge 554
 
378 serge 555
           shl eax, 2
556
           lea eax, [eax+eax*2]     ;eax*=12
168 serge 557
 
378 serge 558
           mov edi, [resampler_params+eax]
559
           mov ecx, [resampler_params+eax+4]
560
           mov ebx, [resampler_params+eax+8]
168 serge 561
 
378 serge 562
           mov [edx+STREAM.r_size],edi
563
           mov [edx+STREAM.r_dt],  ecx
564
           mov [edx+STREAM.resample], ebx
168 serge 565
 
378 serge 566
           mov edi, [edx+STREAM.in_base]
567
           mov ecx, 128/4
568
           mov eax, [edx+STREAM.r_silence]
285 serge 569
           cld
570
           rep stosd
227 serge 571
           xor eax, eax
572
           ret
168 serge 573
.fail:
378 serge 574
           or eax, -1
227 serge 575
           ret
168 serge 576
endp
577
 
378 serge 578
; for static buffers only
579
; use waveout for streams
580
 
168 serge 581
align 4
378 serge 582
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
168 serge 583
 
378 serge 584
           mov edx, [str]
585
           test [edx+STREAM.format], PCM_OUT
586
           jnz .fail
168 serge 587
 
378 serge 588
           mov esi, [src]
589
           mov edi, [offs]
590
           add edi, [edx+STREAM.in_base]
591
           add edi, 128
168 serge 592
 
378 serge 593
           cmp edi, [edx+STREAM.in_top]
594
           jae .fail
168 serge 595
 
378 serge 596
           mov ecx, [size]
597
           lea ebx, [ecx+edi]
598
           sub ebx, [edx+STREAM.in_top]
599
           jb @F
600
           sub ecx, ebx
601
@@:
602
           shr ecx, 2
603
           cld
604
           rep movsd
605
           xor eax,eax
227 serge 606
           ret
168 serge 607
.fail:
378 serge 608
           or eax, -1
227 serge 609
           ret
168 serge 610
endp
611
 
378 serge 612
; for stream buffers only
613
 
168 serge 614
align 4
378 serge 615
proc wave_out stdcall, str:dword,src:dword,size:dword
616
           locals
617
             state_saved  dd ?
618
             fpu_state    rb 528
619
           endl
168 serge 620
 
227 serge 621
           mov edx, [str]
378 serge 622
           mov eax, [edx+STREAM.format]
568 serge 623
           test eax, PCM_OUT
624
           jz .fail
168 serge 625
 
378 serge 626
           cmp ax, PCM_ALL
627
           je .fail
168 serge 628
 
227 serge 629
           mov esi,[src]
630
           test esi, esi
631
           jz .fail
168 serge 632
 
465 serge 633
           cmp esi, OS_BASE
634
           ja .fail
168 serge 635
 
378 serge 636
           mov [state_saved], 0
168 serge 637
 
378 serge 638
.main_loop:
639
           mov edx, [str]
168 serge 640
 
378 serge 641
           mov ebx, [size]
642
           test ebx, ebx
643
           jz .done
644
 
645
           cmp [edx+STREAM.flags], SND_STOP
646
           jne .fill
647
 
648
           mov edi, [edx+STREAM.in_base]
649
           mov ecx, 128/4
650
           mov eax, [edx+STREAM.r_silence]
651
           cld
652
           rep stosd
653
 
654
           mov ecx, [edx+STREAM.in_size]
655
           sub ecx, 128
656
           mov [edx+STREAM.in_wp], edi
657
           mov [edx+STREAM.in_rp], edi
658
           mov [edx+STREAM.in_count], 0
659
           mov [edx+STREAM.in_free], ecx
660
 
661
           mov eax,[edx+STREAM.out_base]
662
           mov [edx+STREAM.out_wp], eax
663
           mov [edx+STREAM.out_rp], eax
664
           mov [edx+STREAM.out_count], 0
665
.fill:
666
           mov ecx, [edx+STREAM.in_free]
667
           test ecx, ecx
668
           jz .wait
669
 
670
           cmp ecx, ebx
671
           jbe @F
672
 
673
           mov ecx, ebx
674
@@:
285 serge 675
           sub [size], ecx
378 serge 676
           add [edx+STREAM.in_count], ecx
677
           sub [edx+STREAM.in_free], ecx
168 serge 678
 
285 serge 679
           shr ecx, 2
378 serge 680
           mov edi, [edx+STREAM.in_wp]
681
           mov esi, [src]
285 serge 682
           cld
683
           rep movsd
378 serge 684
 
685
           mov [src], esi
686
           cmp edi, [edx+STREAM.in_top]
687
           jb @F
688
           sub edi, [edx+STREAM.in_size]
285 serge 689
@@:
378 serge 690
           mov [edx+STREAM.in_wp], edi
168 serge 691
 
378 serge 692
           cmp [edx+STREAM.out_count], 32768
693
           jae .skip
694
 
695
           cmp [state_saved], 0
696
           jne @F
697
           lea eax, [fpu_state+15]
698
           and eax, -16
699
           call FpuSave
700
           mov [state_saved], 1
701
@@:
702
           stdcall refill, edx
703
.skip:
704
           mov ebx, [str]
705
           mov [ebx+STREAM.flags], SND_PLAY
706
           cmp [eng_state], SND_PLAY
707
           je .main_loop
708
 
709
           stdcall dev_play, [hSound]
710
           mov [eng_state], SND_PLAY
711
           jmp .main_loop
712
.wait:
713
           mov edx, [str]
714
           mov eax, [edx+STREAM.notify_event]
715
           mov ebx, [edx+STREAM.notify_id]
716
           call WaitEvent   ;eax ebx
717
           jmp .main_loop
285 serge 718
.done:
378 serge 719
           cmp [state_saved], 1
720
           jne @F
721
 
722
           lea eax, [fpu_state+15]
723
           and eax, -16
724
           call FpuRestore
725
@@:
227 serge 726
           xor eax, eax
378 serge 727
           ret
728
.fail:
729
           or eax, -1
730
           ret
731
endp
732
 
733
; both static and stream
734
; reset all but not clear buffers
735
 
736
 
737
; flags reserved
738
;  RESET_INPUT  equ 1   ;reserved reset and clear input buffer
739
;  RESET_OUTPUT equ 2   ;reserved reset and clear output buffer
740
;  RESET_ALL    equ 3
741
 
742
 
743
align 4
744
proc ResetBuffer stdcall, str:dword, flags:dword
745
 
746
           mov edx, [str]
747
           mov [edx+STREAM.flags], SND_STOP
748
 
749
           mov edi, [edx+STREAM.in_base]
750
           mov ecx, 128/4
751
           mov eax, [edx+STREAM.r_silence]
752
           cld
753
           rep stosd
754
 
755
           mov [edx+STREAM.in_wp], edi
756
           mov [edx+STREAM.in_rp], edi
757
 
567 serge 758
           test [edx+STREAM.flags], PCM_STATIC
759
           jnz .static
378 serge 760
           mov [edx+STREAM.in_count], 0
567 serge 761
           jmp @F
762
.static:
378 serge 763
           mov eax, [edx+STREAM.in_size]
567 serge 764
           mov [edx+STREAM.in_count], eax
765
@@:
766
 
767
           mov eax, [edx+STREAM.in_size]
378 serge 768
           sub eax, 128
769
           mov [edx+STREAM.in_free], eax
770
 
771
           xor eax, eax
772
           mov ebx,[edx+STREAM.out_base]
773
           mov [edx+STREAM.out_wp], ebx
774
           mov [edx+STREAM.out_rp], ebx
775
           mov [edx+STREAM.out_count], eax
776
           ret
777
.fail:
778
           or eax, -1
779
           ret
780
endp
781
 
782
; for static buffers only
783
 
784
align 4
785
proc SetBufferPos stdcall, str:dword, pos:dword
786
 
787
           mov edx, [str]
568 serge 788
           test [edx+STREAM.format], PCM_STATIC
789
           jz .fail
378 serge 790
 
791
           mov [edx+STREAM.flags], SND_STOP
792
 
793
           mov eax, [pos]
794
           add eax, [edx+STREAM.in_base]
795
           mov ebx, [edx+STREAM.in_top]
796
           add eax, 128
797
 
798
           cmp eax, ebx
799
           jae .fail
800
 
801
           mov [edx+STREAM.in_rp], eax
802
           sub ebx, eax
803
           mov [edx+STREAM.in_count], ebx
804
           xor eax, eax
805
           ret
806
.fail:
807
           or eax, -1
808
           ret
809
endp
810
 
811
align 4
812
proc GetBufferPos stdcall, str:dword
813
 
814
           mov edx, [str]
568 serge 815
           test [edx+STREAM.format], PCM_STATIC
816
           jz .fail
378 serge 817
 
818
           mov ebx, [edx+STREAM.in_rp]
567 serge 819
           sub ebx, [edx+STREAM.in_base]
820
           sub ebx, 128
378 serge 821
           xor eax, eax
822
           ret
823
.fail:
824
           xor ebx,ebx
825
           or eax, -1
826
           ret
827
endp
828
 
829
; both
830
 
831
align 4
832
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword
833
 
834
           mov edx, [str]
835
           stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan]
836
           ret
837
endp
838
 
839
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword
840
           locals
841
             _600    dd ?
842
             _32767  dd ?
843
             state   rb 108
844
           endl
845
 
846
           mov [_600], 0x44160000   ;600.0
847
           mov [_32767], 32767
848
 
849
           lea ebx, [state]
850
           fnsave [ebx]
851
 
852
           movq mm0, qword [l_vol]
853
           pminsw mm0, qword [vol_max]
854
           pmaxsw mm0, qword [vol_min]
855
           movq qword [l_vol], mm0
856
           movq qword [edx+STREAM.l_vol], mm0
857
 
858
           movd mm1,[pan]
859
           pminsw mm1, qword [pan_max]
860
           pmaxsw mm1, qword [vol_min]
861
           movd [edx+STREAM.pan], mm1
862
 
863
           cmp word [edx+STREAM.pan], 0
864
           jl @F
865
 
866
           psubsw mm0,mm1
867
           pminsw mm0, qword [vol_max]
868
           pmaxsw mm0, qword [vol_min]
869
           movd [l_vol],mm0
870
           jmp .calc_amp
871
@@:
872
           punpckhdq mm0,mm0
873
           paddsw mm0,mm1
874
           pminsw mm0, qword [vol_max]
875
           pmaxsw mm0, qword [vol_min]
876
           movd [r_vol], mm0
877
.calc_amp:
878
           emms
879
           fild word [l_vol]
880
 
881
           call .calc
882
 
883
           fistp word [edx+STREAM.l_amp]
884
           fstp st0
885
 
886
           fild word [r_vol]
887
 
888
           call .calc
889
 
890
           fistp word [edx+STREAM.r_amp]
891
           fstp st0
892
 
893
           fnclex
894
           lea ebx, [state]
895
           frstor [ebx]
896
 
897
           xor eax, eax
227 serge 898
           inc eax
899
           ret
378 serge 900
.calc:
901
           fdiv dword [_600]
902
           fld st0
903
           frndint
904
           fxch st1
905
           fsub st, st1
906
           f2xm1
907
           fld1
908
           faddp st1, st0
909
           fscale
910
           fimul dword [_32767]
911
           ret 0
912
endp
913
 
914
align 4
915
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword
916
 
917
           mov edx, [str]
918
           mov eax, [p_lvol]
919
           movsx ecx, word [edx+STREAM.l_vol]
920
           mov [eax], ecx
921
 
922
           mov eax, [p_rvol]
923
           movsx ecx, word [edx+STREAM.r_vol]
924
           mov [eax], ecx
925
           xor eax, eax
926
           ret
927
endp
928
 
929
align 4
930
proc SetBufferPan stdcall, str:dword,pan:dword
931
 
932
           mov edx, [str]
933
           stdcall set_vol_param,[edx+STREAM.l_vol],\
934
                                 [edx+STREAM.r_vol],[pan]
935
           ret
936
endp
937
 
938
; for static and ring buffers only
939
 
940
align 4
941
proc play_buffer stdcall, str:dword, flags:dword
942
 
943
           mov ebx, [str]
944
           mov eax, [ebx+STREAM.format]
945
           test eax, PCM_OUT
946
           jnz .fail
947
 
948
           cmp ax, PCM_ALL
949
           je .fail
950
 
951
           mov [ebx+STREAM.flags], SND_PLAY
952
           cmp [eng_state], SND_PLAY
953
           je .done
954
 
955
           stdcall  dev_play, [hSound]
956
           mov [eng_state], SND_PLAY
957
.done:
958
           test [flags], PLAY_SYNC
959
           jz @F
960
 
961
           mov edx, [str]
962
.wait:
963
           mov eax, [edx+STREAM.notify_event]
964
           mov ebx, [edx+STREAM.notify_id]
965
           call WaitEvent   ;eax ebx
966
 
967
           mov edx, [str]
968
           cmp [edx+STREAM.flags], SND_STOP
969
           jne .wait
970
@@:
971
           xor eax, eax
972
           ret
168 serge 973
.fail:
378 serge 974
           or eax, -1
975
           ret
976
endp
977
 
567 serge 978
; for static and ring buffers only
378 serge 979
 
980
align 4
981
proc stop_buffer stdcall, str:dword
982
 
983
           mov edx, [str]
984
           test [edx+STREAM.format], PCM_STATIC+PCM_RING
985
           jz .fail
986
 
987
           mov [edx+STREAM.flags], SND_STOP
988
 
989
;           stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
990
 
991
           mov eax, [edx+STREAM.notify_event]
992
           mov ebx, [edx+STREAM.notify_id]
993
           call ClearEvent   ;eax ebx
994
 
227 serge 995
           xor eax, eax
996
           ret
378 serge 997
.fail:
998
           or eax, -1
999
           ret
168 serge 1000
endp
1001
 
378 serge 1002
; parm
1003
;  eax= mix_list
1004
 
168 serge 1005
align 4
378 serge 1006
do_mix_list:
1007
 
1008
           xor edx, edx
1009
           mov esi, str.fd-FD_OFFSET
1010
           mov ebx, [esi+STREAM.str_fd]
1011
@@:
1012
           cmp ebx, esi
1013
           je .done
1014
 
1015
           cmp [ebx+STREAM.magic], 'WAVE'
1016
           jne .next
1017
 
1018
           cmp [ebx+STREAM.size], STREAM_SIZE
1019
           jne .next
1020
 
1021
           cmp [ebx+STREAM.flags], SND_PLAY;
1022
           jne .next
1023
 
1024
           mov ecx, [ebx+STREAM.out_count]
1025
           test ecx, ecx
1026
           jnz .l1
1027
 
1028
           test [ebx+STREAM.format], PCM_RING
1029
           jnz .next
1030
           mov [ebx+STREAM.flags], SND_STOP
1031
           jmp .next
1032
.l1:
1033
           cmp ecx, 512
1034
           jae .add_buff
1035
 
1036
           mov edi, [ebx+STREAM.out_rp]
1037
           add edi, ecx
1038
           sub ecx, 512
1039
           neg ecx
1040
           push eax
1041
           xor eax, eax
1042
           cld
1043
           rep stosb
1044
           pop eax
1045
 
1046
           mov [ebx+STREAM.out_count], 512
1047
 
1048
.add_buff:
1049
           mov ecx, [ebx+STREAM.out_rp]
1050
           mov [eax],ecx
1051
           mov edi, dword [ebx+STREAM.l_amp]
1052
           mov [eax+4], edi
1053
           add [ebx+STREAM.out_rp], 512
1054
           sub [ebx+STREAM.out_count], 512
1055
 
1056
           add eax, 8
1057
           inc edx
1058
.next:
1059
           mov ebx, [ebx+STREAM.str_fd]
1060
           jmp @B
1061
.done:
1062
           mov eax, edx
1063
           ret
1064
 
1065
align 4
291 serge 1066
prepare_playlist:
168 serge 1067
 
227 serge 1068
           xor edx, edx
291 serge 1069
           mov [play_count], edx
1070
           mov esi, str.fd-FD_OFFSET
1071
           mov edi, [esi+STREAM.str_fd]
1072
@@:
1073
           cmp edi, esi
1074
           je .done
168 serge 1075
 
291 serge 1076
           cmp [edi+STREAM.magic], 'WAVE'
168 serge 1077
           jne .next
1078
 
291 serge 1079
           cmp [edi+STREAM.size], STREAM_SIZE
168 serge 1080
           jne .next
1081
 
291 serge 1082
           cmp [edi+STREAM.flags], SND_PLAY;
227 serge 1083
           jne .next
168 serge 1084
 
291 serge 1085
           mov [play_list+edx], edi
227 serge 1086
           inc [play_count]
1087
           add edx, 4
168 serge 1088
.next:
291 serge 1089
           mov edi, [edi+STREAM.str_fd]
1090
           jmp @B
1091
.done:
227 serge 1092
           ret
168 serge 1093
 
1094
align 4
1095
proc set_handler stdcall, hsrv:dword, handler_proc:dword
1096
           locals
1097
             handler    dd ?
1098
             io_code    dd ?
1099
             input      dd ?
1100
             inp_size   dd ?
1101
             output     dd ?
1102
             out_size   dd ?
1103
             val        dd ?
1104
           endl
1105
 
1106
           mov eax, [hsrv]
1107
           lea ecx, [handler_proc]
1108
           xor ebx, ebx
1109
 
1110
           mov [handler], eax
1111
           mov [io_code], DEV_CALLBACK
1112
           mov [input], ecx
1113
           mov [inp_size], 4
1114
           mov [output], ebx
1115
           mov [out_size], 0
1116
 
1117
           lea eax, [handler]
188 serge 1118
           stdcall ServiceHandler, eax
168 serge 1119
           ret
1120
endp
1121
 
1122
align 4
1123
proc dev_play stdcall, hsrv:dword
1124
           locals
1125
             handle     dd ?
1126
             io_code    dd ?
1127
             input      dd ?
1128
             inp_size   dd ?
1129
             output     dd ?
1130
             out_size   dd ?
1131
             val        dd ?
1132
           endl
1133
 
1134
           mov eax, [hsrv]
1135
           xor ebx, ebx
1136
 
1137
           mov [handle], eax
1138
           mov [io_code], DEV_PLAY
1139
           mov [input], ebx
1140
           mov [inp_size], ebx
1141
           mov [output], ebx
1142
           mov [out_size], ebx
1143
 
1144
           lea eax, [handle]
188 serge 1145
           stdcall ServiceHandler, eax
168 serge 1146
           ret
1147
endp
1148
 
378 serge 1149
if 0
1150
align 4
1151
dword2str:
1152
      mov  esi, hex_buff
1153
      mov ecx, -8
1154
@@:
1155
      rol eax, 4
1156
      mov ebx, eax
1157
      and ebx, 0x0F
1158
      mov bl, [ebx+hexletters]
1159
      mov [8+esi+ecx], bl
1160
      inc ecx
1161
      jnz @B
1162
      ret
1163
 
1164
hexletters   db '0123456789ABCDEF'
1165
hex_buff     db 8 dup(0),13,10,0
1166
 
1167
end if
1168
 
168 serge 1169
include 'mixer.asm'
293 serge 1170
include 'mix_mmx.inc'
1171
include 'mix_sse2.inc'
168 serge 1172
 
291 serge 1173
;if USE_SSE
1174
; include 'mix_sse.inc'
1175
;end if
1176
 
168 serge 1177
align 16
1178
resampler_params:
378 serge 1179
     ;r_size    r_dt   resampler_func
1180
     dd 0,0,0                                  ; 0  PCM_ALL
1181
     dd 16384,      0, copy_stream    ; 1  PCM_2_16_48
1182
     dd 16384,      0, m16_stereo     ; 2  PCM_1_16_48
168 serge 1183
 
378 serge 1184
     dd 16384,  30109, resample_2     ; 3  PCM_2_16_44
1185
     dd  8192,  30109, resample_1     ; 4  PCM_1_16_44
168 serge 1186
 
378 serge 1187
     dd 16384,  21846, resample_2     ; 5  PCM_2_16_32
1188
     dd  8192,  21846, resample_1     ; 6  PCM_1_16_32
168 serge 1189
 
378 serge 1190
     dd 16384,  16384, resample_2     ; 7  PCM_2_16_24
1191
     dd  8192,  16384, resample_1     ; 8  PCM_1_16_24
168 serge 1192
 
378 serge 1193
     dd  8192,  15052, resample_2     ; 9  PCM_2_16_22
1194
     dd  4096,  15052, resample_1     ;10  PCM_1_16_22
168 serge 1195
 
378 serge 1196
     dd  8192,  10923, resample_2     ;11  PCM_2_16_16
1197
     dd  4096,  10923, resample_1     ;12  PCM_1_16_16
168 serge 1198
 
378 serge 1199
     dd  8192,   8192, resample_2     ;13  PCM_2_16_12
1200
     dd  4096,   8192, resample_1     ;14  PCM_1_16_12
168 serge 1201
 
378 serge 1202
     dd  4096,   7527, resample_2     ;15  PCM_2_16_11
1203
     dd  2048,   7527, resample_1     ;16  PCM_1_16_11
168 serge 1204
 
378 serge 1205
     dd  4096,   5462, resample_2     ;17  PCM_2_16_8
1206
     dd  2048,   5462, resample_1     ;18  PCM_1_16_8
168 serge 1207
 
378 serge 1208
     dd 16384,      0, s8_stereo      ;19  PCM_2_8_48
1209
     dd  8192,      0, m8_stereo      ;20  PCM_1_8_48
168 serge 1210
 
378 serge 1211
     dd  8192,  30109, resample_28    ;21  PCM_2_8_44
1212
     dd  4096,  30109, resample_18    ;22  PCM_1_8_44
168 serge 1213
 
378 serge 1214
     dd  8192,  21846, resample_28    ;23  PCM_2_8_32
1215
     dd  4096,  21846, resample_18    ;24  PCM_1_8_32
168 serge 1216
 
378 serge 1217
     dd  8192,  16384, resample_28    ;25  PCM_2_8_24
1218
     dd  4096,  16384, resample_18    ;26  PCM_1_8_24
168 serge 1219
 
378 serge 1220
     dd  4096,  15052, resample_28    ;27  PCM_2_8_22
1221
     dd  2048,  15052, resample_18    ;28  PCM_1_8_22
168 serge 1222
 
378 serge 1223
     dd  4096,  10923, resample_28    ;29  PCM_2_8_16
1224
     dd  2048,  10923, resample_18    ;30  PCM_1_8_16
168 serge 1225
 
378 serge 1226
     dd  4096,   8192, resample_28    ;31  PCM_2_8_12
1227
     dd  2048,   8192, resample_18    ;32  PCM_1_8_12
168 serge 1228
 
378 serge 1229
     dd  2048,   7527, resample_28    ;33  PCM_2_8_11
1230
     dd  1024,   7527, resample_18    ;34  PCM_1_8_11
168 serge 1231
 
378 serge 1232
     dd  2048,   5462, resample_28    ;35  PCM_2_8_8
1233
     dd  1024,   5462, resample_18    ;36  PCM_1_8_8
168 serge 1234
 
281 serge 1235
m7            dw 0x8000,0x8000,0x8000,0x8000
1236
mm80          dq 0x8080808080808080
1237
mm_mask       dq 0xFF00FF00FF00FF00
168 serge 1238
 
378 serge 1239
vol_max       dd 0x00000000,0x00000000
1240
vol_min       dd 0x0000D8F0,0x0000D8F0
1241
pan_max       dd 0x00002710,0x00002710
1242
 
291 serge 1243
;stream_map    dd 0xFFFF       ; 16
465 serge 1244
version       dd (5 shl 16) or (SOUND_VERSION and 0xFFFF)
168 serge 1245
 
281 serge 1246
szInfinity    db 'INFINITY',0
1247
szSound       db 'SOUND',0
168 serge 1248
 
1249
if DEBUG
281 serge 1250
msgFail       db 'Sound service not loaded',13,10,0
1251
msgPlay       db 'Play buffer',13,10,0
1252
msgStop       db 'Stop',13,10,0
1253
msgUser       db 'User callback',13,10,0
1254
msgMem        db 'Not enough memory',13,10,0
291 serge 1255
msgDestroy    db 'Destroy sound buffer', 13,10,0
378 serge 1256
msgWaveout    db 'Play waveout', 13,10,0
1257
msgSetVolume  db 'Set volume',13,10,0
168 serge 1258
end if
188 serge 1259
 
1260
section '.data' data readable writable align 16
1261
 
281 serge 1262
play_list     rd 16
1263
mix_input     rd 16
1264
play_count    rd 1
1265
hSound        rd 1
378 serge 1266
eng_state     rd 1
281 serge 1267
mix_buff      rd 1
1268
mix_buff_map  rd 1
291 serge 1269
str.fd        rd 1
1270
str.bk        rd 1
188 serge 1271
 
293 serge 1272
mix_2_core    rd 1
1273
mix_3_core    rd 1
1274
mix_4_core    rd 1
291 serge 1275