Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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