Subversion Repositories Kolibri OS

Rev

Rev 2987 | 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
3232 Serge 878
;  RESET_INPUT  equ 1   ;reset and clear input buffer
879
;  RESET_OUTPUT equ 2   ;reset and clear output buffer
378 serge 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
3232 Serge 916
 
917
        mov     dword [edx+STREAM.time_base], eax
918
        mov     dword [edx+STREAM.time_base+4], eax
919
 
920
        mov     dword [edx+STREAM.time_stamp], eax
921
        mov     dword [edx+STREAM.time_stamp+4], eax
922
        mov     dword [edx+STREAM.last_ts], eax
923
 
924
 
925
        mov     eax, [edx+STREAM.r_silence]
926
        test    [flags], 1
927
        jz      @F
928
 
929
        mov     ecx, [edx+STREAM.in_top]
930
        mov     edi, [edx+STREAM.in_base]
931
        sub     ecx, edi
932
        shr     ecx, 2
933
        cld
934
        rep stosd
935
@@:
936
        test    [flags], 2
937
        jz      @F
938
 
939
        mov     edi, [edx+STREAM.out_base]
940
        mov     ecx, (64*1024)/4
941
        rep stosd
942
@@:
2434 Serge 943
        ret
378 serge 944
.fail:
2434 Serge 945
        or      eax, -1
946
        ret
378 serge 947
endp
948
 
949
; for static buffers only
950
 
951
align 4
952
proc SetBufferPos stdcall, str:dword, pos: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     [edx+STREAM.flags], SND_STOP
378 serge 959
 
2434 Serge 960
        mov     eax, [pos]
961
        add     eax, [edx+STREAM.in_base]
962
        mov     ebx, [edx+STREAM.in_top]
963
        add     eax, 128
378 serge 964
 
2434 Serge 965
        cmp     eax, ebx
966
        jae     .fail
378 serge 967
 
2434 Serge 968
        mov     [edx+STREAM.in_rp], eax
969
        sub     ebx, eax
970
        mov     [edx+STREAM.in_count], ebx
971
        xor     eax, eax
972
        ret
378 serge 973
.fail:
2434 Serge 974
        or      eax, -1
975
        ret
378 serge 976
endp
977
 
978
align 4
979
proc GetBufferPos stdcall, str:dword
980
 
2434 Serge 981
        mov     edx, [str]
982
        test    [edx+STREAM.format], PCM_STATIC
983
        jz      .fail
378 serge 984
 
2434 Serge 985
        mov     ebx, [edx+STREAM.in_rp]
986
        sub     ebx, [edx+STREAM.in_base]
987
        sub     ebx, 128
988
        xor     eax, eax
989
        ret
378 serge 990
.fail:
2434 Serge 991
        xor     ebx, ebx
992
        or      eax, -1
993
        ret
378 serge 994
endp
995
 
996
; both
997
 
998
align 4
999
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword
1000
 
2434 Serge 1001
        mov     edx, [str]
1002
        stdcall set_vol_param, [l_vol], [r_vol], [edx+STREAM.pan]
1003
        ret
378 serge 1004
endp
1005
 
2010 serge 1006
 
1007
proc minw stdcall, arg1:dword, arg2:dword
2434 Serge 1008
        mov     ax, word [arg1]
1009
        cmp     ax, word [arg2]
1010
        jle     @f
1011
        mov     eax, [arg2]
2010 serge 1012
@@:
2434 Serge 1013
        ret
2010 serge 1014
endp
1015
 
1016
proc maxw stdcall, arg1:dword, arg2:dword
2434 Serge 1017
        mov     ax, word [arg1]
1018
        cmp     ax, word [arg2]
1019
        jge     @f
1020
        mov     eax, [arg2]
2010 serge 1021
@@:
2434 Serge 1022
        ret
2010 serge 1023
endp
1024
 
1025
 
378 serge 1026
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword
1027
           locals
1028
             _600    dd ?
1029
             _32767  dd ?
1030
             state   rb 108
1031
           endl
1032
 
2434 Serge 1033
        mov     [_600], 0x44160000  ;600.0
1034
        mov     [_32767], 32767
378 serge 1035
 
2434 Serge 1036
        lea     ebx, [state]
1037
        fnsave  [ebx]
378 serge 1038
 
2434 Serge 1039
        stdcall minw, [l_vol], [vol_max]
1040
        stdcall maxw, eax, [vol_min]
1041
        mov     [l_vol], eax
1042
        mov     [edx+STREAM.l_vol], eax
1043
        stdcall minw, [r_vol], [vol_max+4]
1044
        stdcall maxw, eax, [vol_min+4]
1045
        mov     [r_vol], eax
1046
        mov     [edx+STREAM.r_vol], eax
378 serge 1047
 
2434 Serge 1048
        stdcall minw, [pan], [pan_max]
1049
        stdcall maxw, eax, [vol_min]
1050
        mov     [edx+STREAM.pan], eax
378 serge 1051
 
2434 Serge 1052
        cmp     word [edx+STREAM.pan], 0
1053
        jl      @f
378 serge 1054
 
2434 Serge 1055
        mov     ebx, [l_vol]
1056
        sub     ebx, eax
1057
        stdcall minw, ebx, [vol_max]
1058
        stdcall maxw, eax, [vol_min]
1059
        mov     [l_vol], eax
1060
        jmp     .calc_amp
378 serge 1061
@@:
2434 Serge 1062
        mov     ebx, [r_vol]
1063
        add     ebx, [pan]
1064
        stdcall minw, ebx, [vol_max+4]
1065
        stdcall maxw, eax, [vol_min+4]
1066
        mov     [r_vol], eax
378 serge 1067
.calc_amp:
2434 Serge 1068
        emms
1069
        fild    word [l_vol]
378 serge 1070
 
2434 Serge 1071
        call    .calc
378 serge 1072
 
2434 Serge 1073
        fistp   word [edx+STREAM.l_amp]
1074
        fstp    dword [edx+STREAM.l_amp_f]
1075
        fstp    st0
378 serge 1076
 
2434 Serge 1077
        fild    word [r_vol]
378 serge 1078
 
2434 Serge 1079
        call    .calc
378 serge 1080
 
2434 Serge 1081
        fistp   word [edx+STREAM.r_amp]
1082
        fstp    dword [edx+STREAM.r_amp_f]
1083
        fstp    st0
378 serge 1084
 
2434 Serge 1085
        fnclex
1086
        lea     ebx, [state]
1087
        frstor  [ebx]
378 serge 1088
 
2434 Serge 1089
        xor     eax, eax
1090
        inc     eax
1091
        ret
378 serge 1092
.calc:
2434 Serge 1093
        fdiv    dword [_600]
1094
        fld     st0
1095
        frndint
1096
        fxch    st1
1097
        fsub    st, st1
1098
        f2xm1
1099
        fld1
1100
        faddp   st1, st0
1101
        fscale
1102
        fld     st0
1103
        fimul   dword [_32767]
1104
        ret     0
378 serge 1105
endp
1106
 
2010 serge 1107
 
378 serge 1108
align 4
1109
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword
1110
 
2434 Serge 1111
        mov     edx, [str]
1112
        mov     eax, [p_lvol]
1113
        movsx   ecx, word [edx+STREAM.l_vol]
1114
        mov     [eax], ecx
378 serge 1115
 
2434 Serge 1116
        mov     eax, [p_rvol]
1117
        movsx   ecx, word [edx+STREAM.r_vol]
1118
        mov     [eax], ecx
1119
        xor     eax, eax
1120
        ret
378 serge 1121
endp
1122
 
1123
align 4
1124
proc SetBufferPan stdcall, str:dword,pan:dword
1125
 
2434 Serge 1126
        mov     edx, [str]
1127
        stdcall set_vol_param, [edx+STREAM.l_vol], \
1128
                [edx+STREAM.r_vol],[pan]
1129
        ret
378 serge 1130
endp
1131
 
1132
; for static and ring buffers only
1133
 
1134
align 4
1135
proc play_buffer stdcall, str:dword, flags:dword
1136
 
2434 Serge 1137
        mov     ebx, [str]
1138
        mov     eax, [ebx+STREAM.format]
1139
        test    eax, PCM_OUT
1140
        jnz     .fail
378 serge 1141
 
2434 Serge 1142
        cmp     ax, PCM_ALL
1143
        je      .fail
378 serge 1144
 
2434 Serge 1145
        mov     [ebx+STREAM.flags], SND_PLAY
1146
        cmp     [eng_state], SND_PLAY
1147
        je      .done
378 serge 1148
 
2434 Serge 1149
        stdcall dev_play, [hSound]
1150
        mov     [eng_state], SND_PLAY
378 serge 1151
.done:
2434 Serge 1152
        test    [flags], PLAY_SYNC
1153
        jz      @F
378 serge 1154
 
2434 Serge 1155
        mov     edx, [str]
378 serge 1156
.wait:
2434 Serge 1157
        mov     eax, [edx+STREAM.notify_event]
1158
        mov     ebx, [edx+STREAM.notify_id]
1159
        call    WaitEvent   ;eax ebx
378 serge 1160
 
2434 Serge 1161
        mov     edx, [str]
1162
        cmp     [edx+STREAM.flags], SND_STOP
1163
        jne     .wait
378 serge 1164
@@:
2434 Serge 1165
        xor     eax, eax
1166
        ret
168 serge 1167
.fail:
2434 Serge 1168
        or      eax, -1
1169
        ret
378 serge 1170
endp
1171
 
567 serge 1172
; for static and ring buffers only
378 serge 1173
 
1174
align 4
1175
proc stop_buffer stdcall, str:dword
1176
 
2434 Serge 1177
        mov     edx, [str]
1178
        test    [edx+STREAM.format], PCM_STATIC+PCM_RING
1179
        jz      .fail
378 serge 1180
 
2434 Serge 1181
        mov     [edx+STREAM.flags], SND_STOP
378 serge 1182
 
2434 Serge 1183
        mov     eax, [edx+STREAM.notify_event]
1184
        mov     ebx, [edx+STREAM.notify_id]
1185
        call    ClearEvent   ;eax ebx
378 serge 1186
 
2434 Serge 1187
        xor     eax, eax
1188
        ret
378 serge 1189
.fail:
2434 Serge 1190
        or      eax, -1
1191
        ret
168 serge 1192
endp
1193
 
695 serge 1194
; param
378 serge 1195
;  eax= mix_list
1196
 
168 serge 1197
align 4
378 serge 1198
do_mix_list:
1199
 
2434 Serge 1200
        xor     edx, edx
1201
        mov     esi, str.fd-FD_OFFSET
1202
        mov     ebx, [esi+STREAM.str_fd]
378 serge 1203
@@:
2434 Serge 1204
        cmp     ebx, esi
1205
        je      .done
378 serge 1206
 
2434 Serge 1207
        cmp     [ebx+STREAM.magic], 'WAVE'
1208
        jne     .next
378 serge 1209
 
2434 Serge 1210
        cmp     [ebx+STREAM.size], STREAM.sizeof
1211
        jne     .next
378 serge 1212
 
2434 Serge 1213
        cmp     [ebx+STREAM.flags], SND_PLAY;
1214
        jne     .next
378 serge 1215
 
2434 Serge 1216
        mov     ecx, [ebx+STREAM.out_count]
1217
        test    ecx, ecx
1218
        jnz     .l1
378 serge 1219
 
2434 Serge 1220
        test    [ebx+STREAM.format], PCM_RING
1221
        jnz     .next
1222
        mov     [ebx+STREAM.flags], SND_STOP
1223
        jmp     .next
378 serge 1224
.l1:
2434 Serge 1225
        cmp     ecx, 512
1226
        jae     .add_buff
378 serge 1227
 
2434 Serge 1228
        mov     edi, [ebx+STREAM.out_rp]
1229
        add     edi, ecx
1230
        sub     ecx, 512
1231
        neg     ecx
1232
        push    eax
1233
        xor     eax, eax
1234
        cld
1235
        rep stosb
1236
        pop     eax
378 serge 1237
 
2434 Serge 1238
        mov     [ebx+STREAM.out_count], 512
378 serge 1239
 
1240
.add_buff:
2434 Serge 1241
        mov     ecx, [ebx+STREAM.out_rp]
1242
        mov     [eax], ecx
694 serge 1243
 
1244
if USE_SSE2_MIXER
2434 Serge 1245
        mov     edi, dword [ebx+STREAM.l_amp_f]
1246
        mov     [eax+4], edi
1247
        mov     edi, dword [ebx+STREAM.r_amp_f]
1248
        mov     [eax+8], edi
694 serge 1249
else
2434 Serge 1250
        mov     edi, dword [ebx+STREAM.l_amp]
1251
        mov     [eax+4], edi
694 serge 1252
end if
2434 Serge 1253
        add     [ebx+STREAM.out_rp], 512
1254
        sub     [ebx+STREAM.out_count], 512
378 serge 1255
 
2434 Serge 1256
        add     eax, 12
1257
        inc     edx
378 serge 1258
.next:
2434 Serge 1259
        mov     ebx, [ebx+STREAM.str_fd]
1260
        jmp     @B
378 serge 1261
.done:
2434 Serge 1262
        mov     eax, edx
1263
        ret
378 serge 1264
 
1265
align 4
291 serge 1266
prepare_playlist:
168 serge 1267
 
2434 Serge 1268
        xor     edx, edx
1269
        mov     [play_count], edx
1270
        mov     esi, str.fd-FD_OFFSET
1271
        mov     edi, [esi+STREAM.str_fd]
291 serge 1272
@@:
2434 Serge 1273
        cmp     edi, esi
1274
        je      .done
168 serge 1275
 
2434 Serge 1276
        cmp     [edi+STREAM.magic], 'WAVE'
1277
        jne     .next
168 serge 1278
 
2434 Serge 1279
        cmp     [edi+STREAM.size], STREAM.sizeof
1280
        jne     .next
168 serge 1281
 
2434 Serge 1282
        cmp     [edi+STREAM.flags], SND_PLAY;
1283
        jne     .next
168 serge 1284
 
2434 Serge 1285
        mov     [play_list+edx], edi
1286
        inc     [play_count]
1287
        add     edx, 4
168 serge 1288
.next:
2434 Serge 1289
        mov     edi, [edi+STREAM.str_fd]
1290
        jmp     @B
291 serge 1291
.done:
2434 Serge 1292
        ret
168 serge 1293
 
1294
align 4
1295
proc set_handler stdcall, hsrv:dword, handler_proc:dword
1296
           locals
1297
             handler    dd ?
1298
             io_code    dd ?
1299
             input      dd ?
1300
             inp_size   dd ?
1301
             output     dd ?
1302
             out_size   dd ?
1303
             val        dd ?
1304
           endl
1305
 
2434 Serge 1306
        mov     eax, [hsrv]
1307
        lea     ecx, [handler_proc]
1308
        xor     ebx, ebx
168 serge 1309
 
2434 Serge 1310
        mov     [handler], eax
1311
        mov     [io_code], DEV_CALLBACK
1312
        mov     [input], ecx
1313
        mov     [inp_size], 4
1314
        mov     [output], ebx
1315
        mov     [out_size], 0
168 serge 1316
 
2434 Serge 1317
        lea     eax, [handler]
1318
        stdcall ServiceHandler, eax
1319
        ret
168 serge 1320
endp
1321
 
1322
align 4
1323
proc dev_play stdcall, hsrv:dword
1324
           locals
1325
             handle     dd ?
1326
             io_code    dd ?
1327
             input      dd ?
1328
             inp_size   dd ?
1329
             output     dd ?
1330
             out_size   dd ?
1331
             val        dd ?
1332
           endl
1333
 
2434 Serge 1334
        mov     eax, [hsrv]
1335
        xor     ebx, ebx
168 serge 1336
 
2434 Serge 1337
        mov     [handle], eax
1338
        mov     [io_code], DEV_PLAY
1339
        mov     [input], ebx
1340
        mov     [inp_size], ebx
1341
        mov     [output], ebx
1342
        mov     [out_size], ebx
168 serge 1343
 
2434 Serge 1344
        lea     eax, [handle]
1345
        stdcall ServiceHandler, eax
1346
        ret
168 serge 1347
endp
1348
 
378 serge 1349
if 0
1350
align 4
1351
dword2str:
2434 Serge 1352
        mov     esi, hex_buff
1353
        mov     ecx, -8
378 serge 1354
@@:
2434 Serge 1355
        rol     eax, 4
1356
        mov     ebx, eax
1357
        and     ebx, 0x0F
1358
        mov     bl, [ebx+hexletters]
1359
        mov     [8+esi+ecx], bl
1360
        inc     ecx
1361
        jnz     @B
1362
        ret
378 serge 1363
 
1364
hexletters   db '0123456789ABCDEF'
1365
hex_buff     db 8 dup(0),13,10,0
1366
 
1367
end if
1368
 
168 serge 1369
include 'mixer.asm'
293 serge 1370
include 'mix_mmx.inc'
1371
include 'mix_sse2.inc'
168 serge 1372
 
291 serge 1373
;if USE_SSE
1374
; include 'mix_sse.inc'
1375
;end if
1376
 
168 serge 1377
align 16
1378
resampler_params:
378 serge 1379
     ;r_size    r_dt   resampler_func
1380
     dd 0,0,0                                  ; 0  PCM_ALL
1381
     dd 16384,      0, copy_stream    ; 1  PCM_2_16_48
802 serge 1382
     dd  8192,      0, m16_stereo     ; 2  PCM_1_16_48
168 serge 1383
 
378 serge 1384
     dd 16384,  30109, resample_2     ; 3  PCM_2_16_44
1385
     dd  8192,  30109, resample_1     ; 4  PCM_1_16_44
168 serge 1386
 
378 serge 1387
     dd 16384,  21846, resample_2     ; 5  PCM_2_16_32
1388
     dd  8192,  21846, resample_1     ; 6  PCM_1_16_32
168 serge 1389
 
378 serge 1390
     dd 16384,  16384, resample_2     ; 7  PCM_2_16_24
1391
     dd  8192,  16384, resample_1     ; 8  PCM_1_16_24
168 serge 1392
 
378 serge 1393
     dd  8192,  15052, resample_2     ; 9  PCM_2_16_22
1394
     dd  4096,  15052, resample_1     ;10  PCM_1_16_22
168 serge 1395
 
378 serge 1396
     dd  8192,  10923, resample_2     ;11  PCM_2_16_16
1397
     dd  4096,  10923, resample_1     ;12  PCM_1_16_16
168 serge 1398
 
378 serge 1399
     dd  8192,   8192, resample_2     ;13  PCM_2_16_12
1400
     dd  4096,   8192, resample_1     ;14  PCM_1_16_12
168 serge 1401
 
378 serge 1402
     dd  4096,   7527, resample_2     ;15  PCM_2_16_11
1403
     dd  2048,   7527, resample_1     ;16  PCM_1_16_11
168 serge 1404
 
378 serge 1405
     dd  4096,   5462, resample_2     ;17  PCM_2_16_8
1406
     dd  2048,   5462, resample_1     ;18  PCM_1_16_8
168 serge 1407
 
378 serge 1408
     dd 16384,      0, s8_stereo      ;19  PCM_2_8_48
1409
     dd  8192,      0, m8_stereo      ;20  PCM_1_8_48
168 serge 1410
 
378 serge 1411
     dd  8192,  30109, resample_28    ;21  PCM_2_8_44
1412
     dd  4096,  30109, resample_18    ;22  PCM_1_8_44
168 serge 1413
 
378 serge 1414
     dd  8192,  21846, resample_28    ;23  PCM_2_8_32
1415
     dd  4096,  21846, resample_18    ;24  PCM_1_8_32
168 serge 1416
 
378 serge 1417
     dd  8192,  16384, resample_28    ;25  PCM_2_8_24
1418
     dd  4096,  16384, resample_18    ;26  PCM_1_8_24
168 serge 1419
 
378 serge 1420
     dd  4096,  15052, resample_28    ;27  PCM_2_8_22
1421
     dd  2048,  15052, resample_18    ;28  PCM_1_8_22
168 serge 1422
 
378 serge 1423
     dd  4096,  10923, resample_28    ;29  PCM_2_8_16
1424
     dd  2048,  10923, resample_18    ;30  PCM_1_8_16
168 serge 1425
 
378 serge 1426
     dd  4096,   8192, resample_28    ;31  PCM_2_8_12
1427
     dd  2048,   8192, resample_18    ;32  PCM_1_8_12
168 serge 1428
 
378 serge 1429
     dd  2048,   7527, resample_28    ;33  PCM_2_8_11
1430
     dd  1024,   7527, resample_18    ;34  PCM_1_8_11
168 serge 1431
 
378 serge 1432
     dd  2048,   5462, resample_28    ;35  PCM_2_8_8
1433
     dd  1024,   5462, resample_18    ;36  PCM_1_8_8
168 serge 1434
 
281 serge 1435
m7            dw 0x8000,0x8000,0x8000,0x8000
1436
mm80          dq 0x8080808080808080
1437
mm_mask       dq 0xFF00FF00FF00FF00
168 serge 1438
 
378 serge 1439
vol_max       dd 0x00000000,0x00000000
1440
vol_min       dd 0x0000D8F0,0x0000D8F0
1441
pan_max       dd 0x00002710,0x00002710
1442
 
291 serge 1443
;stream_map    dd 0xFFFF       ; 16
574 serge 1444
version       dd (5 shl 16) or SOUND_VERSION
168 serge 1445
 
281 serge 1446
szInfinity    db 'INFINITY',0
1447
szSound       db 'SOUND',0
168 serge 1448
 
1449
if DEBUG
281 serge 1450
msgFail       db 'Sound service not loaded',13,10,0
1451
msgPlay       db 'Play buffer',13,10,0
1452
msgStop       db 'Stop',13,10,0
1453
msgUser       db 'User callback',13,10,0
1454
msgMem        db 'Not enough memory',13,10,0
291 serge 1455
msgDestroy    db 'Destroy sound buffer', 13,10,0
378 serge 1456
msgWaveout    db 'Play waveout', 13,10,0
1457
msgSetVolume  db 'Set volume',13,10,0
168 serge 1458
end if
188 serge 1459
 
1460
section '.data' data readable writable align 16
1461
 
281 serge 1462
play_list     rd 16
1463
mix_input     rd 16
1464
play_count    rd 1
1465
hSound        rd 1
378 serge 1466
eng_state     rd 1
281 serge 1467
mix_buff      rd 1
1468
mix_buff_map  rd 1
291 serge 1469
str.fd        rd 1
1470
str.bk        rd 1
188 serge 1471
 
293 serge 1472
mix_2_core    rd 1
1473
mix_3_core    rd 1
1474
mix_4_core    rd 1