Subversion Repositories Kolibri OS

Rev

Rev 4323 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4323 yogev_ezra 1
SSMIX_CHANMODE_FREE   equ 0
2
SSMIX_CHANMODE_SINGLE equ 1
3
SSMIX_CHANMODE_REPEAT equ 2
4
SSMIX_CHANMODE_SINGLE_WITHOUT_RESET equ 3
5
SSMIX_CHANMODE_WAITRESET equ 4
6
 
7
include  'snd.inc'
8
include  'snd_const.inc'
5093 clevermous 9
include  '../../proc32.inc'
4323 yogev_ezra 10
;include  'macros.inc'
11
;include  'debug.inc'
12
 
13
SSMIX_CHANNEL_COUNT equ 32
14
 
15
DEBUG equ 0 ; 0
16
 
17
 
18
; инициализация микшера
19
ssmix_init:
20
; выделить память для каналов микшера
21
    mov  eax, 68
22
    mov  ebx, 12
23
    mov  ecx, 4*8*SSMIX_CHANNEL_COUNT
24
    int  0x40
25
    mov  [ssmix_channels], eax
26
; выделить память для стека потока микшера
27
    mov  eax, 68
28
    mov  ebx, 12
29
    mov  ecx, 4096
30
    int  0x40
31
    mov  [ssmix_thread_stack], eax
32
; включить микшер
33
    mov  [ssmix_state], 1
34
; установить громкости стереоканалов
35
    mov  [ssmix_volumeL], 128
36
    mov  [ssmix_volumeR], 128
37
; создать поток
38
    mov  eax, 51
39
    mov  ebx, 1
40
    mov  ecx, ssmix_thread_proc
41
    mov  edx,[ssmix_thread_stack]
42
    add  edx,4092
43
    int 0x40
44
 
45
    ret
46
 
47
 
48
 
49
; завершение работы микшера
50
ssmix_release:
51
; выключить микшер
52
    mov  [ssmix_state], 0
53
 
54
    ret
55
 
56
 
57
 
58
; освобождение памяти
59
ssmix_free:
60
; освободить память каналов микшера
61
    mov  eax, 68
62
    mov  ebx, 13
63
    mov  ecx, [ssmix_channels]
64
    int  0x40
65
; освободить память стека потока микшера
66
    mov  eax, 68
67
    mov  ebx, 13
68
    mov  ecx, [ssmix_thread_stack]
69
    int  0x40
70
 
71
    ret
72
 
73
; установить громкость
74
ssmix_setvolume:  ; stdcall
75
		  ; LeftVolume: dword, RightVolume: dword
76
 
77
    push  eax
78
    mov   eax, [esp+8]	 ; громкость левого канала
79
    cmp   eax, 255
80
    jle   @f
81
    mov   eax, 255
82
  @@:
83
    cmp   eax, 0
84
    jge   @f
85
    mov   eax, 0
86
  @@:
87
    mov   [ssmix_volumeL], eax
88
 
89
    mov   eax, [esp+12]   ; громкость правого канала
90
    cmp   eax, 255
91
    jle   @f
92
    mov   eax, 255
93
  @@:
94
    cmp   eax, 0
95
    jge   @f
96
    mov   eax, 0
97
  @@:
98
    mov   [ssmix_volumeR], eax
99
    pop   eax
100
 
101
    ret
102
 
103
 
104
; воспроизвести трек
105
ssmix_playtrack:  ; stdcall
106
		  ; p_starttrack:dword, p_endtrack:dword, volumeL: dword, volumeR: dword; playmode:dword;
107
		  ; return eax - number of channel, if eax=-1 then no free channel
108
 
109
    push  ebx ecx
110
    mov   ebx, [ssmix_channels]
111
    mov   ecx, SSMIX_CHANNEL_COUNT
112
  .channel_loop:
113
    mov   eax, [ebx]
114
    cmp   eax, SSMIX_CHANMODE_FREE
115
    je	  .find_free_channel
116
    add   ebx, 32
117
    dec   ecx
118
    jnz   .channel_loop
119
    mov   eax, -1
120
    jmp   .end
121
  .find_free_channel:
122
    mov   eax, [esp+28]   ; режим воспроизведения
123
    mov   [ebx], eax
124
    mov   eax, [esp+20]   ; громкость левого канала
125
    imul  eax, [ssmix_volumeL]
126
    sar   eax, 7
127
    mov   [ebx+4], eax
128
    mov   eax, [esp+24]   ; громкость правого канала
129
    imul  eax, [ssmix_volumeR]
130
    sar   eax, 7
131
    mov   [ebx+8], eax
132
    mov   eax, [esp+12]   ; начало трека
133
    mov   [ebx+16], eax
134
    mov   [ebx+20], eax
135
    mov   eax, [esp+16]   ; конец трека
136
    mov   [ebx+24], eax
137
    mov   eax, SSMIX_CHANNEL_COUNT
138
    sub   eax, ecx
139
  .end:
140
    pop   ecx ebx
141
 
142
    ret   20
143
 
144
 
145
; остановить трек по номеру канала
146
ssmix_stoptrack:    ; stdcall
147
		    ; numchannel: dword
148
    push  eax ebx
149
    mov   ebx, [esp+12]
150
    cmp   ebx, 0
151
    jl	  .end
152
    cmp   ebx, SSMIX_CHANNEL_COUNT
153
    jge   .end
154
    shl   ebx, 5
155
    add   ebx, [ssmix_channels]
156
    mov   eax, SSMIX_CHANMODE_FREE
157
    mov   [ebx], eax
158
  .end:
159
    pop   ebx eax
160
 
161
    ret   4
162
 
163
 
164
; остановить все треки
165
ssmix_stopalltracks:
166
 
167
    push  eax ebx ecx
168
    mov   eax, SSMIX_CHANMODE_FREE
169
    mov   ebx, [ssmix_channels]
170
    mov   ecx, SSMIX_CHANNEL_COUNT
171
  .channel_loop:
172
    mov   [ebx], eax
173
    add   ebx, 32
174
    dec   ecx
175
    jnz   .channel_loop
176
    pop   ecx ebx eax
177
 
178
    ret
179
 
180
 
181
; поток микшера
182
ssmix_thread_proc:
183
 
184
    stdcall  _InitSound@4, ssmix_driver_version
185
    test eax, eax
186
    jz	@f
187
    if DEBUG
188
       print "ssmix. Cannot load sound driver"
189
    end if
190
    jmp  .end
191
  @@:
192
 
193
    mov  ecx, [ssmix_driver_version]
194
    cmp  cx, SOUND_VERSION
195
    jae  @f
196
    shr  ecx, 16
197
    cmp  ecx, SOUND_VERSION
198
    jbe  @f
199
    if DEBUG
200
       print "ssmix. Sound version mismatch"
201
    end if
202
    jmp  .end
203
  @@:
204
 
205
    stdcall _CreateBuffer@12, PCM_2_16_11+PCM_RING, 0, ssmix_hbuffer
206
    test eax, eax
207
    jz	@f
208
    if DEBUG
209
       print "ssmix. create buffer error"
210
    end if
211
    jmp  .end
212
  @@:
213
 
214
    stdcall _GetBufferSize@8, [ssmix_hbuffer], ssmix_buffer_size
215
    test eax, eax
216
    jz	@f
217
    if DEBUG
218
       print "ssmix. getbuffersize procedure error"
219
    end if
220
    jmp  .destroy_buffer
221
  @@:
222
 
223
    mov  ecx, [ssmix_buffer_size]
224
    shr  ecx, 1
225
    mov  [ssmix_buffer_size], ecx
226
    if DEBUG
227
	print "ssmix. buffer size"
228
	dph  ecx
229
	newline
230
    end if
231
 
232
    ; выделить память для буффера воспроизведения
233
    mov  eax, 68
234
    mov  ebx, 12
235
    mov  ecx, [ssmix_buffer_size]
236
    int  0x40
237
    test eax, eax
238
    jnz  @f
239
    if DEBUG
240
       print "ssmix. malloc memory error"
241
    end if
242
    jmp  .destroy_buffer
243
  @@:
244
    mov  [ssmix_pbuffer], eax
245
 
246
    stdcall _PlayBuffer@8, [ssmix_hbuffer], 0
247
    test eax, eax
248
    jz	 @f
249
    if DEBUG
250
       print "ssmix. playbuffer error"
251
    end if
252
    jmp  .free_buffer_memory
253
  @@:
254
 
255
; цикл воспроизведения
256
  .mixloop:
257
; получить данные события от драйвера
258
    mov  eax, 68
259
    mov  ebx, 14
260
    mov  ecx, ssmix_driver_notify_struct
261
    int  0x40
262
; проверка на code
263
    mov  eax, [ssmix_driver_notify_struct]
264
    cmp  eax, 0xFF000001
265
    jne  .mixloop
266
; проверка на stream
267
    mov  eax, [ssmix_driver_notify_struct+8]
268
    cmp  eax, [ssmix_hbuffer]
269
    jne  .mixloop
270
; получить смещение в буффере
271
    mov  eax, [ssmix_driver_notify_struct+12]
272
    mov  [ssmix_buffer_offset], eax
273
; цикл заполнения буффера
274
    mov  ebx, [ssmix_pbuffer]
275
    mov  ecx, [ssmix_buffer_size]
276
    shr  ecx, 2
277
  .fill_buffer_loop:
278
    push  ebx ecx
279
; цикл смешивания каналов
280
    mov   esi, 0    ; сумма для левого стереоканала
281
    mov   edi, 0    ; сумма для правого стереоканала
282
    mov   edx, [ssmix_channels]
283
    mov   ecx, SSMIX_CHANNEL_COUNT
284
  .channel_loop:
285
    mov   eax, [edx]
286
    cmp   eax, SSMIX_CHANMODE_FREE
287
    je	  .channel_end
288
    cmp   eax, SSMIX_CHANMODE_WAITRESET
289
    je	  .channel_end
290
    push  ecx
291
; смешивание каналов с учетом громкости
292
    mov   ebx, [edx+4]
293
    mov   ecx, [edx+16]
294
    movsx eax, word [ecx]
295
    imul  eax, ebx
296
    add   esi, eax
297
    mov   ebx, [edx+8]
298
    movsx eax, word [ecx+2]
299
    imul  eax, ebx
300
    add   edi, eax
301
; проверка на завершение трека
302
    add   ecx, 4
303
    cmp   ecx, [edx+24]
304
    jb	  .notrackend
305
    mov   eax, [edx]
306
    cmp   eax, SSMIX_CHANMODE_SINGLE
307
    jne    @f
308
    mov   ebx, SSMIX_CHANMODE_FREE
309
    mov   [edx], ebx
310
    jmp   .notrackend
311
  @@:
312
    cmp   eax, SSMIX_CHANMODE_REPEAT
313
    jne    @f
314
    mov   ecx, [edx+20]
315
    jmp   .notrackend
316
  @@:
317
    cmp   eax, SSMIX_CHANMODE_SINGLE_WITHOUT_RESET
318
    jne    @f
319
    mov   ebx, SSMIX_CHANMODE_WAITRESET
320
    mov   [edx], ebx
321
    jmp   .notrackend
322
  @@:
323
  .notrackend:
324
    mov   [edx+16], ecx
325
    pop   ecx
326
  .channel_end:
327
    add   edx, 32
328
    dec   ecx
329
    jnz   .channel_loop
330
; нормализация стереоканалов
331
    sar   esi, 7
332
    cmp   esi, 0x7FFF
333
    jle   @f
334
    mov   esi, 0x7FFF
335
  @@:
336
    cmp   esi, -0x8000
337
    jge   @f
338
    mov   esi, -0x8000
339
  @@:
340
    sar   edi, 7
341
    cmp   edi, 0x7FFF
342
    jle   @f
343
    mov   edi, 0x7FFF
344
  @@:
345
    cmp   edi, -0x8000
346
    jge   @f
347
    mov   edi, -0x8000
348
  @@:
349
; сохранение результата в буффере микшера
350
    shl   edi, 16
351
    add   esi, edi
352
    pop   ecx ebx
353
    mov  [ebx], esi
354
    add  ebx, 4
355
    dec  ecx
356
    jnz  .fill_buffer_loop
357
; установка буффера драйвера
358
    stdcall _SetBuffer@16, [ssmix_hbuffer], [ssmix_pbuffer], [ssmix_buffer_offset], [ssmix_buffer_size]
359
    cmp  [ssmix_state], 1
360
    je	 .mixloop
361
 
362
; освободить память буффера воспроизведения
363
  .free_buffer_memory:
364
    mov  eax, 68
365
    mov  ebx, 13
366
    mov  ecx, [ssmix_pbuffer]
367
; уничтожить буффер драйвера
368
  .destroy_buffer:
369
    stdcall _DestroyBuffer@4, [ssmix_hbuffer]
370
 
371
; завершить работу потока
372
  .end:
373
    call  ssmix_free
374
    mov   eax, -1
375
    int   0x40
376
 
377
    ;ret
378
 
379
 
380
;=================================================================================
381
 
382
align 4
383
_InitSound@4:	    ;p_ver:dword
384
 
385
	   push ebx
386
	   push ecx
387
 
388
	   mov eax, 68
389
	   mov ebx, 16
390
	   mov ecx, ssmix_szInfinity
391
	   int 0x40
392
	   mov [ssmix_hSound], eax
393
	   test eax, eax
394
	   jz .fail
395
 
396
	   mov eax, 68
397
	   mov ebx, 16
398
	   mov ecx, ssmix_szSound
399
	   int 0x40
400
	   mov [ssmix_hrdwSound], eax
401
 
402
	   lea eax, [esp+12]   ;p_ver
403
	   xor ebx, ebx
404
 
405
	   push 4	       ;.out_size
406
	   push eax	       ;.output
407
	   push ebx	       ;.inp_size
408
	   push ebx	       ;.input
409
	   push SRV_GETVERSION ;.code
410
	   push [ssmix_hSound]	     ;.handle
411
 
412
	   mov eax, 68
413
	   mov ebx, 17
414
	   mov ecx, esp        ;[handle]
415
	   int 0x40
416
	   add esp, 24
417
	   pop ecx
418
	   pop ebx
419
	   ret 4
420
.fail:
421
	   or eax, -1
422
	   pop ecx
423
	   pop ebx
424
	   ret 4
425
 
426
 
427
align 4
428
_CreateBuffer@12:   ;format:dword,size:dword,p_str:dword
429
 
430
	   push ebx
431
	   push ecx
432
	   lea eax, [esp+20]   ;p_str
433
	   lea ebx, [esp+12]   ;format
434
 
435
	   push 4	       ;.out_size
436
	   push eax	       ;.output
437
	   push 8	       ;.inp_size
438
	   push ebx	       ;.input
439
	   push SND_CREATE_BUFF;.code
440
	   push [ssmix_hSound]	     ;.handle
441
 
442
	   mov eax, 68
443
	   mov ebx, 17
444
	   mov ecx, esp
445
	   int 0x40
446
	   add esp, 24	     ;io_cintrol
447
	   pop ecx
448
	   pop ebx
449
	   ret 12
450
 
451
align 4
452
_DestroyBuffer@4:     ;str:dword
453
 
454
	   push ebx
455
	   push ecx
456
 
457
	   xor eax, eax
458
	   lea ebx, [esp+12]   ;[stream]
459
 
460
	   push eax	       ;.out_size
461
	   push eax	       ;.output
462
	   push 4	       ;.inp_size
463
	   push ebx	       ;.input
464
	   push SND_DESTROY_BUFF;.code
465
	   push [ssmix_hSound]	     ;.handle
466
 
467
	   mov eax, 68
468
	   mov ebx, 17
469
	   mov ecx, esp        ;[handle]
470
	   int 0x40
471
	   add esp, 24
472
	   pop ecx
473
	   pop ebx
474
	   ret 4
475
 
476
align 4
477
_GetBufferSize@8:      ;str:dword, p_size:dword
478
 
479
	   push ebx
480
	   push ecx
481
 
482
	   lea eax, [esp+16]
483
	   lea ebx, [esp+12]   ;[stream]
484
 
485
	   push 4	       ;.out_size
486
	   push eax	       ;.output
487
	   push 4	       ;.inp_size
488
	   push ebx	       ;.input
489
	   push SND_GETBUFFSIZE;.code
490
	   push dword [ssmix_hSound] ;.handle
491
 
492
	   mov eax, 68
493
	   mov ebx, 17
494
	   mov ecx, esp
495
	   int 0x40
496
	   add esp, 24
497
	   pop ecx
498
	   pop ebx
499
	   ret 8
500
 
501
align 4
502
_SetBuffer@16:	 ;str:dword, src:dword, offs:dword, size:dword
503
 
504
	   push ebx
505
	   push ecx
506
 
507
	   xor eax, eax
508
	   lea ebx, [esp+12]   ;[stream]
509
 
510
	   push eax	       ;.out_size
511
	   push eax	       ;.output
512
	   push 16	       ;.inp_size
513
	   push ebx	       ;.input
514
	   push SND_SETBUFF    ;.code
515
	   push dword [ssmix_hSound] ;.handle
516
 
517
	   mov eax, 68
518
	   mov ebx, 17
519
	   mov ecx, esp
520
	   int 0x40
521
	   add esp, 24
522
	   pop ecx
523
	   pop ebx
524
	   ret 16
525
 
526
align 4
527
_PlayBuffer@8:		;str:dword,flags:dword
528
 
529
	   push ebx
530
	   push ecx
531
 
532
	   xor eax, eax
533
	   lea ebx, [esp+12]   ;[stream]
534
 
535
	   push eax	       ;.out_size
536
	   push eax	       ;.output
537
	   push 8	       ;.inp_size
538
	   push ebx	       ;.input
539
	   push SND_PLAY       ;.code
540
	   push dword [ssmix_hSound] ;.handle
541
 
542
	   mov eax, 68
543
	   mov ebx, 17
544
	   mov ecx, esp
545
	   int 0x40
546
	   add esp, 24
547
	   pop ecx
548
	   pop ebx
549
	   ret 8
550
 
551
 
552
 
553
; ========================= data  =====================================
554
 
555
ssmix_hSound	  dd ?
556
ssmix_hrdwSound   dd ?
557
 
558
ssmix_szInfinity  db 'INFINITY',0
559
ssmix_szSound	  db 'SOUND',0
560
 
561
ssmix_channels dd 0
562
ssmix_thread_stack dd 0
563
ssmix_state dd 0
564
ssmix_volumeL dd ?
565
ssmix_volumeR dd ?
566
ssmix_driver_version dd ?
567
ssmix_hbuffer dd ?
568
ssmix_pbuffer dd 0
569
ssmix_buffer_size dd ?
570
ssmix_buffer_offset dd ?
571
ssmix_driver_notify_struct rd 6   ; сткуктура события от драйвера