Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
168 serge 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
 
21
DEBUG		    equ 1
22
 
23
EVENT_NOTIFY	    equ 0x00000200
24
 
25
OS_BASE               equ 0;  0x80400000
26
new_app_base          equ 0x60400000;   0x01000000
27
PROC_BASE             equ OS_BASE+0x0080000
28
 
188 serge 29
public START
168 serge 30
public service_proc
31
 
188 serge 32
extrn AttachIntHandler
33
extrn SysMsgBoardStr
34
extrn PciApi
35
extrn PciRead32
36
extrn PciRead8
37
extrn PciWrite8
38
extrn AllocKernelSpace
39
extrn MapPage
40
extrn RegService
41
extrn KernelAlloc
42
extrn KernelFree
43
extrn GetPgAddr
44
extrn GetCurrentTask
45
extrn GetService
46
extrn ServiceHandler
47
extrn FpuSave
48
extrn FpuRestore
49
 
168 serge 50
SND_CREATE_BUFF     equ 2
51
SND_PLAY            equ 3
52
SND_STOP            equ 4
53
SND_SETBUFF         equ 5
54
SND_DESTROY_BUFF    equ 6
55
 
56
DEV_PLAY            equ 1
57
DEV_STOP            equ 2
58
DEV_CALLBACK        equ 3
59
 
60
struc IOCTL
61
{  .handle           dd ?
62
   .io_code          dd ?
63
   .input            dd ?
64
   .inp_size         dd ?
65
   .output           dd ?
66
   .out_size         dd ?
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
 
77
           mov eax, [state]
78
           cmp eax, 1
79
           je .entry
80
           jmp .exit
81
.entry:
188 serge 82
           stdcall GetService, szSound
168 serge 83
           test eax, eax
84
           jz .fail
85
           mov [hSound], eax
86
 
188 serge 87
           stdcall KernelAlloc, 16*512
168 serge 88
           test eax, eax
89
           jz .out_of_mem
90
           mov [mix_buff], eax
91
 
92
           mov edi, stream_list
93
           mov ecx, 17
94
           xor eax, eax
95
           cld
96
           rep stosd
97
 
98
           mov edi, stream
99
           mov ecx, 4*STREAM_SIZE
100
           rep stosd
188 serge 101
           mov [stream_count],0
168 serge 102
 
103
           stdcall set_handler, [hSound], new_mix
188 serge 104
           stdcall RegService, szInfinity, service_proc
168 serge 105
	   ret
106
.fail:
107
     if DEBUG
108
	   mov esi, msgFail
188 serge 109
           call SysMsgBoardStr
168 serge 110
     end if
214 serge 111
.exit:
168 serge 112
	   xor eax, eax
113
	   ret
114
 
115
.out_of_mem:
116
     if DEBUG
117
           mov esi, msgMem
188 serge 118
           call SysMsgBoardStr
168 serge 119
     end if
120
	   xor eax, eax
188 serge 121
           ret
214 serge 122
endp
168 serge 123
 
124
handle     equ  IOCTL.handle
125
io_code    equ  IOCTL.io_code
126
input      equ  IOCTL.input
127
inp_size   equ  IOCTL.inp_size
128
output     equ  IOCTL.output
129
out_size   equ  IOCTL.out_size
130
 
131
align 4
132
proc service_proc stdcall, ioctl:dword
133
 
134
           mov edi, [ioctl]
135
           mov eax, [edi+io_code]
136
 
137
	   cmp eax, SND_CREATE_BUFF
138
	   jne @F
139
           mov ebx, [edi+input]
140
           stdcall CreateBuffer,[ebx]
141
	   ret
142
@@:
143
	   cmp eax, SND_PLAY
144
	   jne @F
145
 
146
           mov ebx, [edi+input]
147
	   stdcall play_buffer, [ebx]
148
	   ret
149
@@:
150
	   cmp eax, SND_STOP
151
	   jne @F
152
 
153
;       if DEBUG
154
;	   mov esi, msgStop
155
;	   call   [SysMsgBoardStr]
156
;       end if
157
 
158
           mov ebx, [edi+input]
159
	   stdcall stop_buffer, [ebx]
160
	   ret
161
@@:
162
	   cmp eax, SND_SETBUFF
163
	   jne @F
164
 
165
           mov ebx, [edi+input]
166
	   mov eax, [ebx+4]
167
	   add eax, new_app_base
168
	   stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12]
169
	   ret
170
@@:
171
           cmp eax, SND_DESTROY_BUFF
172
	   jne @F
173
 
174
           mov ebx, [edi+input]
175
           stdcall DestroyBuffer, [ebx]
176
	   ret
177
@@:
178
	   xor eax, eax
179
	   ret
180
endp
181
 
182
restore   handle
183
restore   io_code
184
restore   input
185
restore   inp_size
186
restore   output
187
restore   out_size
188
 
189
TASK_COUNT    equ 0x0003004
190
CURRENT_TASK  equ 0x0003000
191
 
192
align 8
193
proc CreateBuffer stdcall, format:dword
194
	   locals
195
	      str dd ?
196
	   endl
197
 
198
	   call alloc_stream
199
	   and eax, eax
200
	   jz .fail
201
	   mov [str], eax
202
           mov edi, eax
203
 
204
	   mov edx, [stream_count]
205
	   mov [stream_list+edx*4], eax
206
	   inc [stream_count]
207
 
208
	   mov [edi+STREAM.magic], 'WAVE'
209
	   mov [edi+STREAM.size], STREAM_SIZE
210
 
188 serge 211
           stdcall KernelAlloc, 180*1024
168 serge 212
 
213
	   mov edi, [str]
214
	   mov [edi+STREAM.base], eax
215
	   mov [edi+STREAM.curr_seg], eax
216
	   mov [edi+STREAM.notify_off1], eax
217
	   add eax, 0x8000
218
	   mov [edi+STREAM.notify_off2], eax
219
	   add eax, 0x7FFF
220
	   mov [edi+STREAM.limit], eax
221
 
222
	   inc eax
223
 
224
	   mov [edi+STREAM.work_buff], eax
225
	   mov [edi+STREAM.work_read], eax
226
	   mov [edi+STREAM.work_write], eax
227
	   mov [edi+STREAM.work_count], 0
228
	   add eax, 0x10000
229
	   mov [edi+STREAM.work_top], eax
230
	   add eax, 1024*32
231
	   mov [edi+STREAM.r_buff], eax
232
 
233
	   mov ebx, [CURRENT_TASK]
234
           shl ebx, 5
235
           mov eax, [0x3000+ebx+4]
236
 
237
	   mov [edi+STREAM.notify_task], eax
238
 
239
	   mov eax, [format]
240
	   mov [edi+STREAM.format], eax
241
	   mov [edi+STREAM.flags], SND_STOP
242
 
243
           xor ebx, ebx
244
           cmp eax, 19
245
           jb @f
246
           mov ebx, 0x80808080
247
@@:
248
           mov [edi+STREAM.r_silence], ebx
249
 
250
	   shl eax, 4
251
           mov ebx, [resampler_params+eax]
252
           mov ecx, [resampler_params+eax+4]
253
           mov edx, [resampler_params+eax+8]
254
 
255
           mov [edi+STREAM.r_size],ebx
256
           mov [edi+STREAM.r_end], ecx
257
           mov [edi+STREAM.r_dt],  edx
258
 
259
	   mov ebx, [resampler_params+eax+12]
260
	   mov [edi+STREAM.resample], ebx
261
 
262
	   mov edi, [edi+STREAM.base]
263
	   mov ecx, 180*1024/4
264
	   xor eax, eax
265
	   rep stosd
266
 
267
	   mov eax, [str]
268
	   ret
269
 
270
.fail:
271
	   xor eax, eax
272
	   ret
273
endp
274
 
275
align 4
276
pid_to_slot:
277
 
278
    push   ebx
279
    push   ecx
280
    mov    ebx,[TASK_COUNT]
281
    shl    ebx,5
282
    mov    ecx,2*32
283
.loop:
284
    cmp    byte [CURRENT_TASK+ecx+0xa],9
285
    jz     .endloop              ;skip empty slots
286
    cmp    [CURRENT_TASK+ecx+0x4],eax ;check PID
287
    jz     .pid_found
288
.endloop:
289
    add    ecx,32
290
    cmp    ecx,ebx
291
    jle    .loop
292
    pop    ecx
293
    pop    ebx
294
    xor    eax,eax
295
    ret
296
 
297
.pid_found:
298
    shr    ecx,5
299
    mov    eax,ecx
300
    pop    ecx
301
    pop    ebx
302
    ret
303
 
304
align 4
305
proc DestroyBuffer stdcall, str:dword
306
 
307
           mov esi, [str]
308
 
309
           cmp [esi+STREAM.magic], 'WAVE'
310
	   jne .fail
311
 
312
           cmp [esi+STREAM.size], STREAM_SIZE
313
	   jne .fail
314
 
188 serge 315
           stdcall KernelFree, [esi+STREAM.base]
168 serge 316
 
317
           mov eax, [str]
318
	   call free_stream
319
 
320
           mov edi, [str]
321
           mov ecx, STREAM_SIZE/4
322
           xor eax, eax
323
           cld
324
           rep stosd
325
 
326
           mov eax, [str]
327
           mov esi, stream_list
328
           mov ecx, 16
329
@@:
330
           cmp [esi], eax
331
           je .remove
332
           add esi, 4
333
           dec ecx
334
           jnz @B
335
           xor eax, eax
336
	   inc eax
337
	   ret
338
.remove:
339
           mov edi, esi
340
           add esi, 4
341
           cld
342
           rep movsd
343
           dec [stream_count]
344
           xor eax, eax
345
	   inc eax
346
	   ret
347
.fail:
348
	   xor eax, eax
349
	   ret
350
endp
351
 
352
align 4
353
proc play_buffer stdcall, str:dword
354
 
355
	   mov ebx, [str]
356
 
357
	   cmp [ebx+STREAM.magic], 'WAVE'
358
	   jne .fail
359
 
360
	   cmp [ebx+STREAM.size], STREAM_SIZE
361
	   jne .fail
362
 
363
	   mov [ebx+STREAM.flags], SND_PLAY
364
 
365
	   mov eax,[ebx+STREAM.work_buff]
366
	   mov [ebx+STREAM.work_read], eax
367
	   mov [ebx+STREAM.work_write], eax
368
	   mov [ebx+STREAM.work_count], 0
369
 
370
	   mov eax, [ebx+STREAM.base]
371
	   mov [ebx+STREAM.curr_seg], eax
372
 
373
	   mov esi, [ebx+STREAM.curr_seg]
374
	   mov edi, [ebx+STREAM.work_write]
375
	   mov edx, [ebx+STREAM.r_buff]
376
 
377
	   mov ecx, 32
378
           mov eax, [ebx+STREAM.r_silence]
379
@@:
380
	   mov [edx], eax
381
	   add edx, 4
382
	   dec ecx
383
	   jnz @B
384
 
385
	   mov edx, [ebx+STREAM.r_buff]
386
 
387
	   stdcall [ebx+STREAM.resample], edi, esi, edx,\
388
	      [ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end]
389
 
390
	   mov ebx, [str]
391
 
392
	   add [ebx+STREAM.work_count], eax;
393
	   add [ebx+STREAM.work_write], eax;
394
 
395
	   mov eax, [ebx+STREAM.r_size]
396
	   add [ebx+STREAM.curr_seg], eax
397
 
398
;       if DEBUG
399
;	   mov esi, msgPlay
400
;	   call   [SysMsgBoardStr]
401
;       end if
402
 
403
	   stdcall  dev_play, [hSound]
404
 
405
	   xor eax, eax
406
	   inc eax
407
	   ret
408
 
409
.fail:
410
	   xor eax, eax
411
	   ret
412
 
413
endp
414
 
415
align 4
416
proc stop_buffer stdcall, str:dword
417
 
418
	   mov edi, [str]
419
 
420
	   cmp [edi+STREAM.magic], 'WAVE'
421
	   jne .fail
422
 
423
	   cmp [edi+STREAM.size], STREAM_SIZE
424
	   jne .fail
425
 
426
	   mov [edi+STREAM.flags], SND_STOP
427
 
428
;           stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
429
 
430
	   xor eax, eax
431
	   inc eax
432
	   ret
433
 
434
.fail:
435
	   xor eax, eax
436
	   ret
437
 
438
endp
439
 
440
align 4
441
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
442
 
443
	   mov edx, [str]
444
	   test edx, edx
445
	   jz .fail
446
 
447
	   cmp [edx+STREAM.magic], 'WAVE'
448
	   jne .fail
449
 
450
	   cmp [edx+STREAM.size], STREAM_SIZE
451
	   jne .fail
452
 
453
	   mov esi,[src]
454
	   test esi, esi
455
	   jz .fail
456
 
457
           cmp esi, new_app_base
458
           jb .fail
459
 
460
	   mov ecx, [size]
461
	   test ecx, ecx
462
	   jz .fail
463
 
464
	   mov eax, [edx+STREAM.base]
465
	   add eax, [offs]
466
 
467
           cmp eax, [edx+STREAM.base]
468
           jb .fail
469
 
470
	   mov edi, eax
471
	   add eax, ecx
472
	   sub eax, 1
473
 
474
	   cmp eax, [edx+STREAM.limit]
475
           ja .fail
476
 
477
	   shr ecx, 2
478
           cld
479
	   rep movsd
480
 
481
	   xor eax, eax
482
	   inc eax
483
	   ret
484
.fail:
485
	   xor eax, eax
486
	   ret
487
endp
488
 
489
align 4
490
proc alloc_stream
491
 
492
	   mov esi, stream_map
493
 
494
	   pushf
495
	   cli
496
 
497
	   bsf eax, [esi]
498
	   jnz .find
499
	   popf
500
	   xor eax, eax
501
	   ret
502
 
503
.find:	   btr [esi], eax
504
	   popf
505
	   mov ebx, STREAM_SIZE
506
	   mul ebx
507
	   add eax, stream
508
	   ret
509
endp
510
 
511
align 4
512
proc free_stream
513
	   sub eax, stream
514
           mov ebx, STREAM_SIZE
515
	   xor edx, edx
516
	   div ebx
517
 
518
	   and edx, edx
519
           jnz .err
520
 
521
	   bts [stream_map], eax
522
 
523
	   ret
524
.err:
525
           xor eax, eax
526
	   ret
527
endp
528
 
529
align 4
530
proc check_stream
531
 
532
	   xor edx, edx
533
	   mov ecx, [play_count]
534
.l1:
535
	   mov esi, [play_list+edx]
536
 
537
	   mov eax, [esi+STR.curr_seg]
538
	   cmp eax, [esi+STR.limit]
539
	   jb .next
540
 
541
.m1:	   mov eax,[esi+STR.base]
542
	   mov [esi+STR.curr_seg], eax
543
.next:
544
	   add edx, 4
545
	   loop .l1
546
	   ret
547
endp
548
 
549
 
550
align 4
551
proc prepare_playlist
552
 
553
.restart:
554
           xor ebx, ebx
555
	   xor edx, edx
556
	   mov [play_count], 0
557
	   mov ecx, [stream_count]
558
           jcxz .exit
559
.l1:
560
           mov esi, [stream_list+ebx]
561
           test esi, esi
562
           jz .next
563
 
564
           cmp [esi+STREAM.magic], 'WAVE'
565
           jne .next
566
 
567
           cmp [esi+STREAM.size], STREAM_SIZE
568
           jne .next
569
 
570
           mov eax,[esi+STREAM.notify_task]
571
           cmp eax, -1
572
           je .fail
573
 
574
           call pid_to_slot
575
           test eax, eax
576
           jz .fail
577
 
578
           cmp [esi+STREAM.flags], SND_PLAY;
579
	   jne .next
580
           cmp [esi+STREAM.work_count], 16384
581
           jb .next
582
 
583
           mov [play_list+edx], esi
584
	   inc [play_count]
585
	   add edx, 4
586
.next:
587
	   add ebx, 4
588
	   loop .l1
589
.exit:
590
	   ret
591
.fail:
592
           stdcall DestroyBuffer, esi
593
           jmp .restart
594
endp
595
 
596
align 4
597
proc prepare_updatelist
598
 
599
	   xor ebx, ebx
600
	   xor edx, edx
601
	   mov [play_count], 0
602
	   mov ecx, [stream_count]
603
           jcxz .exit
604
.l1:
605
	   mov eax, [stream_list+ebx]
606
           test eax, eax
607
           jz .next
608
	   cmp [eax+STREAM.flags], SND_PLAY
609
	   jne .next
610
 
611
	   mov [play_list+edx], eax
612
	   inc [play_count]
613
	   add edx, 4
614
.next:
615
	   add ebx, 4
616
	   loop .l1
617
.exit:
618
	   ret
619
endp
620
 
621
align 4
622
proc set_handler stdcall, hsrv:dword, handler_proc:dword
623
           locals
624
             handler    dd ?
625
             io_code    dd ?
626
             input      dd ?
627
             inp_size   dd ?
628
             output     dd ?
629
             out_size   dd ?
630
             val        dd ?
631
           endl
632
 
633
           mov eax, [hsrv]
634
           lea ecx, [handler_proc]
635
           xor ebx, ebx
636
 
637
           mov [handler], eax
638
           mov [io_code], DEV_CALLBACK
639
           mov [input], ecx
640
           mov [inp_size], 4
641
           mov [output], ebx
642
           mov [out_size], 0
643
 
644
           lea eax, [handler]
188 serge 645
           stdcall ServiceHandler, eax
168 serge 646
           ret
647
endp
648
 
649
align 4
650
proc dev_play stdcall, hsrv:dword
651
           locals
652
             handle     dd ?
653
             io_code    dd ?
654
             input      dd ?
655
             inp_size   dd ?
656
             output     dd ?
657
             out_size   dd ?
658
             val        dd ?
659
           endl
660
 
661
           mov eax, [hsrv]
662
           xor ebx, ebx
663
 
664
           mov [handle], eax
665
           mov [io_code], DEV_PLAY
666
           mov [input], ebx
667
           mov [inp_size], ebx
668
           mov [output], ebx
669
           mov [out_size], ebx
670
 
671
           lea eax, [handle]
188 serge 672
           stdcall ServiceHandler, eax
168 serge 673
           ret
674
endp
675
 
676
include 'mixer.asm'
677
 
678
align 16
679
resampler_params:
680
     ;r_size    r_end   r_dt   resampler_func
681
     dd 0,0,0,0                                  ; 0  PCM_ALL
682
     dd 16384,          0,     0, copy_stream    ; 1  PCM_2_16_48
683
     dd 16384,          0,     0, m16_stereo     ; 2  PCM_1_16_48
684
 
685
     dd 16384, 0x08000000, 30109, resample_2     ; 3  PCM_2_16_44
686
     dd  8192, 0x08000000, 30109, resample_1     ; 4  PCM_1_16_44
687
 
688
     dd 16384, 0x08000000, 21846, resample_2     ; 5  PCM_2_16_32
689
     dd  8192, 0x08000000, 21846, resample_1     ; 6  PCM_1_16_32
690
 
691
     dd 16384, 0x08000000, 16384, resample_2     ; 7  PCM_2_16_24
692
     dd  8192, 0x08000000, 16384, resample_1     ; 8  PCM_1_16_24
693
 
694
     dd  8192, 0x04000000, 15052, resample_2     ; 9  PCM_2_16_22
695
     dd  4096, 0x04000000, 15052, resample_1     ;10  PCM_1_16_22
696
 
697
     dd  8192, 0x04000000, 10923, resample_2     ;11  PCM_2_16_16
698
     dd  4096, 0x04000000, 10923, resample_1     ;12  PCM_1_16_16
699
 
700
     dd  8192, 0x04000000,  8192, resample_2     ;13  PCM_2_16_12
701
     dd  4096, 0x04000000,  8192, resample_1     ;14  PCM_1_16_12
702
 
703
     dd  4096, 0x02000000,  7527, resample_2     ;15  PCM_2_16_11
704
     dd  2048, 0x02000000,  7527, resample_1     ;16  PCM_1_16_11
705
 
706
     dd  4096, 0x02000000,  5462, resample_2     ;17  PCM_2_16_8
707
     dd  2048, 0x02000000,  5462, resample_1     ;18  PCM_1_16_8
708
 
709
     dd 16384,          0,     0, s8_stereo      ;19  PCM_2_8_48
710
     dd  8192,          0,     0, m8_stereo      ;20  PCM_1_8_48
711
 
712
     dd  8192, 0x08000000, 30109, resample_28    ;21  PCM_2_8_44
713
     dd  4096, 0x08000000, 30109, resample_18    ;22  PCM_1_8_44
714
 
715
     dd  8192, 0x08000000, 21846, resample_28    ;23  PCM_2_8_32
716
     dd  4096, 0x08000000, 21846, resample_18    ;24  PCM_1_8_32
717
 
718
     dd  8192, 0x08000000, 16384, resample_28    ;25  PCM_2_8_24
719
     dd  4096, 0x08000000, 16384, resample_18    ;26  PCM_1_8_24
720
 
721
     dd  4096, 0x04000000, 15052, resample_28    ;27  PCM_2_8_22
722
     dd  2048, 0x04000000, 15052, resample_18    ;28  PCM_1_8_22
723
 
724
     dd  4096, 0x04000000, 10923, resample_28    ;29  PCM_2_8_16
725
     dd  2048, 0x04000000, 10923, resample_18    ;30  PCM_1_8_16
726
 
727
     dd  4096, 0x04000000,  8192, resample_28    ;31  PCM_2_8_12
728
     dd  2048, 0x04000000,  8192, resample_18    ;32  PCM_1_8_12
729
 
730
     dd  2048, 0x02000000,  7527, resample_28    ;33  PCM_2_8_11
731
     dd  1024, 0x02000000,  7527, resample_18    ;34  PCM_1_8_11
732
 
733
     dd  2048, 0x02000000,  5462, resample_28    ;35  PCM_2_8_8
734
     dd  1024, 0x02000000,  5462, resample_18    ;36  PCM_1_8_8
735
 
736
m7	     dw 0x8000,0x8000,0x8000,0x8000
737
mm80	     dq 0x8080808080808080
738
mm_mask      dq 0xFF00FF00FF00FF00
739
 
740
stream_map   dd 0xFFFF	      ; 16
741
 
742
szInfinity   db 'INFINITY',0
743
szSound      db 'SOUND',0
744
 
745
if DEBUG
214 serge 746
msgFail      db 'Sound service not loaded',13,10,0
168 serge 747
msgPlay      db 'Play buffer',13,10,0
748
msgStop      db 'Stop',13,10,0
749
msgUser      db 'User callback',13,10,0
750
msgMem       db 'Not enough memory',13,10,0
751
end if
188 serge 752
 
753
section '.data' data readable writable align 16
754
 
755
stream       rb STREAM_SIZE*16
756
 
757
play_list    rd 16
758
mix_input    rd 16
759
 
760
stream_list  rd 17
761
play_count   rd 1
762
stream_count rd 1
763
hSound       rd 1
764
mix_buff     rd 1
765
mix_buff_map rd 1
766