Subversion Repositories Kolibri OS

Rev

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