Subversion Repositories Kolibri OS

Rev

Rev 2455 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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