Subversion Repositories Kolibri OS

Rev

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

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