Subversion Repositories Kolibri OS

Rev

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