Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | /* |
2 | * simple audio Lib .. |
||
3 | * copyrights (c) 1994,1995,1996 by Michael Hipp |
||
4 | * SGI audio support copyrights (c) 1995 by Thomas Woerner |
||
5 | * copy policy: GPL V2.0 |
||
6 | */ |
||
7 | |||
8 | #include <sys/types.h> |
||
9 | #include <stdio.h> |
||
10 | #include <unistd.h> |
||
11 | #include <fcntl.h> |
||
12 | |||
13 | #ifdef SOLARIS |
||
14 | #include <stropts.h> |
||
15 | #include <sys/conf.h> |
||
16 | #endif |
||
17 | |||
18 | #include "mpg123.h" |
||
19 | |||
20 | extern int outburst; |
||
21 | |||
22 | void audio_info_struct_init(struct audio_info_struct *ai) |
||
23 | { |
||
24 | #ifdef AUDIO_USES_FD |
||
25 | ai->fn = -1; |
||
26 | #endif |
||
27 | #ifdef SGI |
||
28 | #if 0 |
||
29 | ALconfig config; |
||
30 | ALport port; |
||
31 | #endif |
||
32 | #endif |
||
33 | ai->rate = -1; |
||
34 | ai->gain = -1; |
||
35 | ai->output = -1; |
||
36 | ai->device = NULL; |
||
37 | ai->channels = -1; |
||
38 | ai->format = -1; |
||
39 | } |
||
40 | |||
41 | |||
42 | #ifdef OS2 |
||
43 | #include <stdlib.h> |
||
44 | #include <os2.h> |
||
45 | #define INCL_OS2MM |
||
46 | #include <os2me.h> |
||
47 | #define BUFNUM 20 |
||
48 | #define BUFSIZE 16384 |
||
49 | #endif |
||
50 | |||
51 | #ifdef VOXWARE |
||
52 | #include <sys/ioctl.h> |
||
53 | #ifdef LINUX |
||
54 | #include <linux/soundcard.h> |
||
55 | #else |
||
56 | #include <machine/soundcard.h> |
||
57 | #endif |
||
58 | |||
59 | int audio_open(struct audio_info_struct *ai) |
||
60 | { |
||
61 | if(!ai) |
||
62 | return -1; |
||
63 | |||
64 | if(!ai->device) |
||
65 | ai->device = "/dev/dsp"; |
||
66 | |||
67 | ai->fn = open(ai->device,O_WRONLY); |
||
68 | |||
69 | if(ai->fn < 0) |
||
70 | { |
||
71 | fprintf(stderr,"Can't open %s!\n",ai->device); |
||
72 | exit(1); |
||
73 | } |
||
74 | |||
75 | ioctl(ai->fn, SNDCTL_DSP_GETBLKSIZE, &outburst); |
||
76 | if(outburst > MAXOUTBURST) |
||
77 | outburst = MAXOUTBURST; |
||
78 | |||
79 | if(audio_reset_parameters(ai) < 0) { |
||
80 | close(ai->fn); |
||
81 | return -1; |
||
82 | } |
||
83 | |||
84 | if(ai->gain >= 0) { |
||
85 | int e,mask; |
||
86 | e = ioctl(ai->fn , SOUND_MIXER_READ_DEVMASK ,&mask); |
||
87 | if(e < 0) { |
||
88 | fprintf(stderr,"audio/gain: Can't get audio device features list.\n"); |
||
89 | } |
||
90 | else if(mask & SOUND_MASK_PCM) { |
||
91 | int gain = (ai->gain<<8)|(ai->gain); |
||
92 | e = ioctl(ai->fn, SOUND_MIXER_WRITE_PCM , &gain); |
||
93 | } |
||
94 | else if(!(mask & SOUND_MASK_VOLUME)) { |
||
95 | fprintf(stderr,"audio/gain: setable Volume/PCM-Level not supported by your audio device: %#04x\n",mask); |
||
96 | } |
||
97 | else { |
||
98 | int gain = (ai->gain<<8)|(ai->gain); |
||
99 | e = ioctl(ai->fn, SOUND_MIXER_WRITE_VOLUME , &gain); |
||
100 | } |
||
101 | } |
||
102 | |||
103 | return ai->fn; |
||
104 | } |
||
105 | |||
106 | int audio_reset_parameters(struct audio_info_struct *ai) |
||
107 | { |
||
108 | int ret; |
||
109 | ret = ioctl(ai->fn,SNDCTL_DSP_RESET,NULL); |
||
110 | if(ret >= 0) |
||
111 | ret = audio_set_format(ai); |
||
112 | if(ret >= 0) |
||
113 | ret = audio_set_channels(ai); |
||
114 | if(ret >= 0) |
||
115 | ret = audio_set_rate(ai); |
||
116 | return ret; |
||
117 | } |
||
118 | |||
119 | int audio_rate_best_match(struct audio_info_struct *ai) |
||
120 | { |
||
121 | int ret,dsp_rate; |
||
122 | |||
123 | if(!ai || ai->fn < 0 || ai->rate < 0) |
||
124 | return -1; |
||
125 | dsp_rate = ai->rate; |
||
126 | ret = ioctl(ai->fn, SNDCTL_DSP_SPEED,&dsp_rate); |
||
127 | if(ret < 0) |
||
128 | return ret; |
||
129 | ai->rate = dsp_rate; |
||
130 | return 0; |
||
131 | } |
||
132 | |||
133 | int audio_set_rate(struct audio_info_struct *ai) |
||
134 | { |
||
135 | int dsp_rate; |
||
136 | |||
137 | if(ai->rate >= 0) { |
||
138 | dsp_rate = ai->rate; |
||
139 | return ioctl(ai->fn, SNDCTL_DSP_SPEED,&dsp_rate); |
||
140 | } |
||
141 | |||
142 | return 0; |
||
143 | } |
||
144 | |||
145 | int audio_set_channels(struct audio_info_struct *ai) |
||
146 | { |
||
147 | int chan = ai->channels - 1; |
||
148 | |||
149 | if(ai->channels < 0) |
||
150 | return 0; |
||
151 | |||
152 | return ioctl(ai->fn, SNDCTL_DSP_STEREO, &chan); |
||
153 | } |
||
154 | |||
155 | int audio_set_format(struct audio_info_struct *ai) |
||
156 | { |
||
157 | int sample_size,fmts; |
||
158 | |||
159 | if(ai->format == -1) |
||
160 | return 0; |
||
161 | |||
162 | switch(ai->format) { |
||
163 | case AUDIO_FORMAT_SIGNED_16: |
||
164 | default: |
||
165 | fmts = AFMT_S16_LE; |
||
166 | sample_size = 16; |
||
167 | break; |
||
168 | case AUDIO_FORMAT_UNSIGNED_8: |
||
169 | fmts = AFMT_U8; |
||
170 | sample_size = 8; |
||
171 | break; |
||
172 | case AUDIO_FORMAT_SIGNED_8: |
||
173 | fmts = AFMT_S8; |
||
174 | sample_size = 8; |
||
175 | break; |
||
176 | case AUDIO_FORMAT_ULAW_8: |
||
177 | fmts = AFMT_MU_LAW; |
||
178 | sample_size = 8; |
||
179 | break; |
||
180 | } |
||
181 | if(ioctl(ai->fn, SNDCTL_DSP_SAMPLESIZE,&sample_size) < 0) |
||
182 | return -1; |
||
183 | return ioctl(ai->fn, SNDCTL_DSP_SETFMT, &fmts); |
||
184 | } |
||
185 | |||
186 | int audio_get_formats(struct audio_info_struct *ai) |
||
187 | { |
||
188 | int ret = 0; |
||
189 | int fmts; |
||
190 | |||
191 | if(ioctl(ai->fn,SNDCTL_DSP_GETFMTS,&fmts) < 0) |
||
192 | return -1; |
||
193 | |||
194 | if(fmts & AFMT_MU_LAW) |
||
195 | ret |= AUDIO_FORMAT_ULAW_8; |
||
196 | if(fmts & AFMT_S16_LE) |
||
197 | ret |= AUDIO_FORMAT_SIGNED_16; |
||
198 | if(fmts & AFMT_U8) |
||
199 | ret |= AUDIO_FORMAT_UNSIGNED_8; |
||
200 | if(fmts & AFMT_S8) |
||
201 | ret |= AUDIO_FORMAT_SIGNED_8; |
||
202 | |||
203 | return ret; |
||
204 | } |
||
205 | |||
206 | int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len) |
||
207 | { |
||
208 | return write(ai->fn,buf,len); |
||
209 | } |
||
210 | |||
211 | int audio_close(struct audio_info_struct *ai) |
||
212 | { |
||
213 | close (ai->fn); |
||
214 | return 0; |
||
215 | } |
||
216 | |||
217 | #elif defined(SOLARIS) || defined(SUNOS) |
||
218 | |||
219 | #include <sys/filio.h> |
||
220 | #ifdef SUNOS |
||
221 | #include <sun/audioio.h> |
||
222 | #else |
||
223 | #include <sys/audioio.h> |
||
224 | #endif |
||
225 | |||
226 | int audio_open(struct audio_info_struct *ai) |
||
227 | { |
||
228 | audio_info_t ainfo; |
||
229 | |||
230 | ai->fn = open("/dev/audio",O_WRONLY); |
||
231 | if(ai->fn < 0) |
||
232 | return ai->fn; |
||
233 | |||
234 | #ifdef SUNOS |
||
235 | { |
||
236 | int type; |
||
237 | if(ioctl(ai->fn, AUDIO_GETDEV, &type) == -1) |
||
238 | return -1; |
||
239 | if(type == AUDIO_DEV_UNKNOWN || type == AUDIO_DEV_AMD) |
||
240 | return -1; |
||
241 | } |
||
242 | #else |
||
243 | #if 0 |
||
244 | { |
||
245 | struct audio_device ad; |
||
246 | if(ioctl(ai->fn, AUDIO_GETDEV, &ad) == -1) |
||
247 | return -1; |
||
248 | fprintf(stderr,"%s\n",ad.name); |
||
249 | if(strstr(ad.name,"CS4231")) |
||
250 | fprintf(stderr,"Warning: Your machine can't play full 44.1Khz stereo.\n"); |
||
251 | if(!strstr(ad.name,"dbri") && !strstr(ad.name,"CS4231")) |
||
252 | fprintf(stderr,"Warning: Unknown sound system %s. But we try it.\n",ad.name); |
||
253 | } |
||
254 | #endif |
||
255 | #endif |
||
256 | |||
257 | if(audio_reset_parameters(ai) < 0) { |
||
258 | return -1; |
||
259 | } |
||
260 | |||
261 | if(ioctl(ai->fn, AUDIO_GETINFO, &ainfo) == -1) |
||
262 | return -1; |
||
263 | |||
264 | switch(ai->output) |
||
265 | { |
||
266 | case AUDIO_OUT_INTERNAL_SPEAKER: |
||
267 | ainfo.play.port = AUDIO_SPEAKER; |
||
268 | break; |
||
269 | case AUDIO_OUT_HEADPHONES: |
||
270 | ainfo.play.port = AUDIO_HEADPHONE; |
||
271 | break; |
||
272 | case AUDIO_OUT_LINE_OUT: |
||
273 | ainfo.play.port = AUDIO_LINE_OUT; |
||
274 | break; |
||
275 | } |
||
276 | |||
277 | if(ai->gain != -1) |
||
278 | ainfo.play.gain = ai->gain; |
||
279 | |||
280 | if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1) |
||
281 | return -1; |
||
282 | |||
283 | return ai->fn; |
||
284 | } |
||
285 | |||
286 | int audio_reset_parameters(struct audio_info_struct *ai) |
||
287 | { |
||
288 | int ret; |
||
289 | ret = audio_set_format(ai); |
||
290 | if(ret >= 0) |
||
291 | ret = audio_set_channels(ai); |
||
292 | if(ret >= 0) |
||
293 | ret = audio_set_rate(ai); |
||
294 | return ret; |
||
295 | } |
||
296 | |||
297 | int audio_rate_best_match(struct audio_info_struct *ai) |
||
298 | { |
||
299 | return 0; |
||
300 | } |
||
301 | |||
302 | int audio_set_rate(struct audio_info_struct *ai) |
||
303 | { |
||
304 | audio_info_t ainfo; |
||
305 | |||
306 | if(ai->rate != -1) |
||
307 | { |
||
308 | if(ioctl(ai->fn, AUDIO_GETINFO, &ainfo) == -1) |
||
309 | return -1; |
||
310 | ainfo.play.sample_rate = ai->rate; |
||
311 | if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1) |
||
312 | return -1; |
||
313 | return 0; |
||
314 | } |
||
315 | return -1; |
||
316 | } |
||
317 | |||
318 | int audio_set_channels(struct audio_info_struct *ai) |
||
319 | { |
||
320 | audio_info_t ainfo; |
||
321 | |||
322 | if(ioctl(ai->fn, AUDIO_GETINFO, &ainfo) == -1) |
||
323 | return -1; |
||
324 | ainfo.play.channels = ai->channels; |
||
325 | if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1) |
||
326 | return -1; |
||
327 | return 0; |
||
328 | } |
||
329 | |||
330 | int audio_set_format(struct audio_info_struct *ai) |
||
331 | { |
||
332 | audio_info_t ainfo; |
||
333 | |||
334 | if(ioctl(ai->fn, AUDIO_GETINFO, &ainfo) == -1) |
||
335 | return -1; |
||
336 | |||
337 | switch(ai->format) { |
||
338 | case -1: |
||
339 | case AUDIO_FORMAT_SIGNED_16: |
||
340 | default: |
||
341 | ainfo.play.encoding = AUDIO_ENCODING_LINEAR; |
||
342 | ainfo.play.precision = 16; |
||
343 | break; |
||
344 | case AUDIO_FORMAT_UNSIGNED_8: |
||
345 | #ifndef SUNOS |
||
346 | ainfo.play.encoding = AUDIO_ENCODING_LINEAR8; |
||
347 | ainfo.play.precision = 8; |
||
348 | break; |
||
349 | #endif |
||
350 | case AUDIO_FORMAT_SIGNED_8: |
||
351 | fprintf(stderr,"Linear signed 8 bit not supported!\n"); |
||
352 | return -1; |
||
353 | case AUDIO_FORMAT_ULAW_8: |
||
354 | ainfo.play.encoding = AUDIO_ENCODING_ULAW; |
||
355 | ainfo.play.precision = 8; |
||
356 | break; |
||
357 | case AUDIO_FORMAT_ALAW_8: |
||
358 | ainfo.play.encoding = AUDIO_ENCODING_ALAW; |
||
359 | ainfo.play.precision = 8; |
||
360 | break; |
||
361 | } |
||
362 | |||
363 | if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1) |
||
364 | return -1; |
||
365 | |||
366 | return 0; |
||
367 | } |
||
368 | |||
369 | int audio_get_formats(struct audio_info_struct *ai) |
||
370 | { |
||
371 | return AUDIO_FORMAT_SIGNED_16|AUDIO_FORMAT_ULAW_8; |
||
372 | } |
||
373 | |||
374 | int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len) |
||
375 | { |
||
376 | return write(ai->fn,buf,len); |
||
377 | } |
||
378 | |||
379 | int audio_close(struct audio_info_struct *ai) |
||
380 | { |
||
381 | close (ai->fn); |
||
382 | return 0; |
||
383 | } |
||
384 | |||
385 | #ifdef SOLARIS |
||
386 | void audio_queueflush (struct audio_info_struct *ai) |
||
387 | { |
||
388 | ioctl (ai->fn, I_FLUSH, FLUSHRW); |
||
389 | } |
||
390 | #endif |
||
391 | |||
392 | |||
393 | #elif defined(HPUX) |
||
394 | #include <sys/audio.h> |
||
395 | |||
396 | int audio_open(struct audio_info_struct *ai) |
||
397 | { |
||
398 | struct audio_describe ades; |
||
399 | struct audio_gain again; |
||
400 | int i,audio; |
||
401 | |||
402 | ai->fn = open("/dev/audio",O_RDWR); |
||
403 | |||
404 | if(ai->fn < 0) |
||
405 | return -1; |
||
406 | |||
407 | |||
408 | ioctl(ai->fn,AUDIO_DESCRIBE,&ades); |
||
409 | |||
410 | if(ai->gain != -1) |
||
411 | { |
||
412 | if(ai->gain > ades.max_transmit_gain) |
||
413 | { |
||
414 | fprintf(stderr,"your gainvalue was to high -> set to maximum.\n"); |
||
415 | ai->gain = ades.max_transmit_gain; |
||
416 | } |
||
417 | if(ai->gain < ades.min_transmit_gain) |
||
418 | { |
||
419 | fprintf(stderr,"your gainvalue was to low -> set to minimum.\n"); |
||
420 | ai->gain = ades.min_transmit_gain; |
||
421 | } |
||
422 | again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1; |
||
423 | ioctl(ai->fn,AUDIO_GET_GAINS,&again); |
||
424 | again.cgain[0].transmit_gain = ai->gain; |
||
425 | again.cgain[1].transmit_gain = ai->gain; |
||
426 | again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1; |
||
427 | ioctl(ai->fn,AUDIO_SET_GAINS,&again); |
||
428 | } |
||
429 | |||
430 | if(ai->output != -1) |
||
431 | { |
||
432 | if(ai->output == AUDIO_OUT_INTERNAL_SPEAKER) |
||
433 | ioctl(ai->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_SPEAKER); |
||
434 | else if(ai->output == AUDIO_OUT_HEADPHONES) |
||
435 | ioctl(ai->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_HEADPHONE); |
||
436 | else if(ai->output == AUDIO_OUT_LINE_OUT) |
||
437 | ioctl(ai->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_LINE); |
||
438 | } |
||
439 | |||
440 | if(ai->rate == -1) |
||
441 | ai->rate = 44100; |
||
442 | |||
443 | for(i=0;i<ades.nrates;i++) |
||
444 | { |
||
445 | if(ai->rate == ades.sample_rate[i]) |
||
446 | break; |
||
447 | } |
||
448 | if(i == ades.nrates) |
||
449 | { |
||
450 | fprintf(stderr,"Can't set sample-rate to %ld.\n",ai->rate); |
||
451 | i = 0; |
||
452 | } |
||
453 | |||
454 | if(audio_reset_parameters(ai) < 0) |
||
455 | return -1; |
||
456 | |||
457 | return ai->fn; |
||
458 | } |
||
459 | |||
460 | int audio_reset_parameters(struct audio_info_struct *ai) |
||
461 | { |
||
462 | int ret; |
||
463 | ret = audio_set_format(ai); |
||
464 | if(ret >= 0) |
||
465 | ret = audio_set_channels(ai); |
||
466 | if(ret >= 0) |
||
467 | ret = audio_set_rate(ai); |
||
468 | return ret; |
||
469 | } |
||
470 | |||
471 | int audio_rate_best_match(struct audio_info_struct *ai) |
||
472 | { |
||
473 | return 0; |
||
474 | } |
||
475 | |||
476 | int audio_set_rate(struct audio_info_struct *ai) |
||
477 | { |
||
478 | if(ai->rate >= 0) |
||
479 | return ioctl(ai->fn,AUDIO_SET_SAMPLE_RATE,ai->rate); |
||
480 | return 0; |
||
481 | } |
||
482 | |||
483 | int audio_set_channels(struct audio_info_struct *ai) |
||
484 | { |
||
485 | return ioctl(ai->fn,AUDIO_SET_CHANNELS,ai->channels); |
||
486 | } |
||
487 | |||
488 | int audio_set_format(struct audio_info_struct *ai) |
||
489 | { |
||
490 | int fmt; |
||
491 | |||
492 | switch(ai->format) { |
||
493 | case -1: |
||
494 | case AUDIO_FORMAT_SIGNED_16: |
||
495 | default: |
||
496 | fmt = AUDIO_FORMAT_LINEAR16BIT; |
||
497 | break; |
||
498 | case AUDIO_FORMAT_UNSIGNED_8: |
||
499 | fprintf(stderr,"unsigned 8 bit linear not supported\n"); |
||
500 | return -1; |
||
501 | case AUDIO_FORMAT_SIGNED_8: |
||
502 | fprintf(stderr,"signed 8 bit linear not supported\n"); |
||
503 | return -1; |
||
504 | case AUDIO_FORMAT_ALAW_8: |
||
505 | fmt = AUDIO_FORMAT_ALAW; |
||
506 | break; |
||
507 | case AUDIO_FORMAT_ULAW_8: |
||
508 | fmt = AUDIO_FORMAT_ULAW; |
||
509 | break; |
||
510 | } |
||
511 | return ioctl(ai->fn,AUDIO_SET_DATA_FORMAT,fmt); |
||
512 | } |
||
513 | |||
514 | int audio_get_formats(struct audio_info_struct *ai) |
||
515 | { |
||
516 | return AUDIO_FORMAT_SIGNED_16; |
||
517 | } |
||
518 | |||
519 | |||
520 | int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len) |
||
521 | { |
||
522 | return write(ai->fn,buf,len); |
||
523 | } |
||
524 | |||
525 | int audio_close(struct audio_info_struct *ai) |
||
526 | { |
||
527 | close (ai->fn); |
||
528 | return 0; |
||
529 | } |
||
530 | |||
531 | #elif defined(SGI) |
||
532 | |||
533 | int audio_open(struct audio_info_struct *ai) |
||
534 | { |
||
535 | ai->config = ALnewconfig(); |
||
536 | |||
537 | if(ai->channels == 2) |
||
538 | ALsetchannels(ai->config, AL_STEREO); |
||
539 | else |
||
540 | ALsetchannels(ai->config, AL_MONO); |
||
541 | ALsetwidth(ai->config, AL_SAMPLE_16); |
||
542 | |||
543 | ALsetqueuesize(ai->config, 131069); |
||
544 | |||
545 | ai->port = ALopenport("mpg132", "w", ai->config); |
||
546 | if(ai->port == NULL){ |
||
547 | fprintf(stderr, "Unable to open audio channel."); |
||
548 | exit(-1); |
||
549 | } |
||
550 | |||
551 | audio_reset_parameters(ai); |
||
552 | |||
553 | return 1; |
||
554 | } |
||
555 | |||
556 | int audio_reset_parameters(struct audio_info_struct *ai) |
||
557 | { |
||
558 | int ret; |
||
559 | ret = audio_set_format(ai); |
||
560 | if(ret >= 0) |
||
561 | ret = audio_set_channels(ai); |
||
562 | if(ret >= 0) |
||
563 | ret = audio_set_rate(ai); |
||
564 | |||
565 | /* todo: Set new parameters here */ |
||
566 | |||
567 | return ret; |
||
568 | } |
||
569 | |||
570 | int audio_rate_best_match(struct audio_info_struct *ai) |
||
571 | { |
||
572 | return 0; |
||
573 | } |
||
574 | |||
575 | int audio_set_rate(struct audio_info_struct *ai) |
||
576 | { |
||
577 | long params[2] = {AL_OUTPUT_RATE, 44100}; |
||
578 | |||
579 | params[1] = ai->rate; |
||
580 | ALsetparams(AL_DEFAULT_DEVICE, params, 2); |
||
581 | return 0; |
||
582 | } |
||
583 | |||
584 | int audio_set_channels(struct audio_info_struct *ai) |
||
585 | { |
||
586 | if(ai->channels == 2) |
||
587 | ALsetchannels(ai->config, AL_STEREO); |
||
588 | else |
||
589 | ALsetchannels(ai->config, AL_MONO); |
||
590 | return 0; |
||
591 | } |
||
592 | |||
593 | int audio_set_format(struct audio_info_struct *ai) |
||
594 | { |
||
595 | return 0; |
||
596 | } |
||
597 | |||
598 | int audio_get_formats(struct audio_info_struct *ai) |
||
599 | { |
||
600 | return AUDIO_FORMAT_SIGNED_16; |
||
601 | } |
||
602 | |||
603 | |||
604 | int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len) |
||
605 | { |
||
606 | if(ai->format == AUDIO_FORMAT_SIGNED_8) |
||
607 | ALwritesamps(ai->port, buf, len); |
||
608 | else |
||
609 | ALwritesamps(ai->port, buf, len>>1); |
||
610 | return len; |
||
611 | } |
||
612 | |||
613 | int audio_close(struct audio_info_struct *ai) |
||
614 | { |
||
615 | while(ALgetfilled(ai->port) > 0) |
||
616 | sginap(1); |
||
617 | ALcloseport(ai->port); |
||
618 | ALfreeconfig(ai->config); |
||
619 | return 0; |
||
620 | } |
||
621 | |||
622 | #elif defined(OS2) |
||
623 | |||
624 | typedef struct { |
||
625 | ULONG operation; |
||
626 | ULONG operand1; |
||
627 | ULONG operand2; |
||
628 | ULONG operand3; |
||
629 | } ple; |
||
630 | MCI_WAVE_SET_PARMS msp; |
||
631 | MCI_PLAY_PARMS mpp; |
||
632 | int id, pos=0; |
||
633 | ple pl[BUFNUM+2]; |
||
634 | |||
635 | int audio_open(struct audio_info_struct *ai) |
||
636 | { |
||
637 | char *buf[BUFNUM]; |
||
638 | int i; |
||
639 | ULONG rc; |
||
640 | MCI_OPEN_PARMS mop; |
||
641 | |||
642 | pl[0].operation = (ULONG)NOP_OPERATION; |
||
643 | pl[0].operand1 = 0; |
||
644 | pl[0].operand2 = 0; |
||
645 | pl[0].operand3 = 0; |
||
646 | for(i = 0; i < BUFNUM; i++) { |
||
647 | buf[i] = (char*)malloc(BUFSIZE); |
||
648 | memset(buf[i], 0, BUFSIZE); |
||
649 | pl[i+1].operation = (ULONG)DATA_OPERATION; |
||
650 | pl[i+1].operand1 = (ULONG)buf[i]; |
||
651 | pl[i+1].operand2 = BUFSIZE/2; |
||
652 | pl[i+1].operand3 = 0; |
||
653 | } |
||
654 | pl[BUFNUM+1].operation = (ULONG)BRANCH_OPERATION; |
||
655 | pl[BUFNUM+1].operand1 = 0; |
||
656 | pl[BUFNUM+1].operand2 = 1; |
||
657 | pl[BUFNUM+1].operand3 = 0; |
||
658 | |||
659 | mop.pszDeviceType = (PSZ)MCI_DEVTYPE_WAVEFORM_AUDIO_NAME; |
||
660 | mop.pszElementName = (PSZ)&pl; |
||
661 | |||
662 | rc = mciSendCommand(0, MCI_OPEN, MCI_WAIT |
||
663 | | MCI_OPEN_PLAYLIST, (PVOID)&mop, 0); |
||
664 | if (rc) { |
||
665 | puts("open audio device failed!"); |
||
666 | exit(1); |
||
667 | } |
||
668 | id = mop.usDeviceID; |
||
669 | |||
670 | msp.usBitsPerSample = 16; |
||
671 | rc = mciSendCommand(id, MCI_SET, MCI_WAIT | MCI_WAVE_SET_BITSPERSAMPLE, (PVOID)&msp, 0); |
||
672 | return 0; |
||
673 | } |
||
674 | |||
675 | int audio_reset_parameters(struct audio_info_struct *ai) |
||
676 | { |
||
677 | static int audio_initialized = FALSE, i; |
||
678 | |||
679 | if (audio_initialized) { |
||
680 | while (pl[pos].operand3 < pl[pos].operand2) _sleep2(125); |
||
681 | for(i = 1; i <= BUFNUM; i++) { |
||
682 | memset((char*)pl[i].operand1, 0, BUFSIZE); |
||
683 | pl[i].operand2 = BUFSIZE; |
||
684 | pl[i].operand3 = 0; |
||
685 | } |
||
686 | _sleep2(2000); |
||
687 | mciSendCommand(id, MCI_STOP, MCI_WAIT, (PVOID)&mpp, 0); |
||
688 | for(i = 1; i <= BUFNUM; i++) { |
||
689 | memset((char*)pl[i].operand1, 0, BUFSIZE); |
||
690 | pl[i].operand2 = BUFSIZE/2; |
||
691 | pl[i].operand3 = 0; |
||
692 | } |
||
693 | pos = 0; |
||
694 | } |
||
695 | msp.ulSamplesPerSec = ai->rate; |
||
696 | msp.usChannels = ai->channels; |
||
697 | mciSendCommand(id, MCI_SET, MCI_WAIT |
||
698 | | MCI_WAVE_SET_SAMPLESPERSEC |
||
699 | | MCI_WAVE_SET_CHANNELS, (PVOID)&msp, 0); |
||
700 | |||
701 | mciSendCommand(id, MCI_PLAY, 0, (PVOID)&mpp, 0); |
||
702 | |||
703 | if(!audio_initialized) audio_initialized = TRUE; |
||
704 | return 0; |
||
705 | } |
||
706 | |||
707 | int audio_rate_best_match(struct audio_info_struct *ai) |
||
708 | { |
||
709 | return 0; |
||
710 | } |
||
711 | |||
712 | int audio_set_rate(struct audio_info_struct *ai) |
||
713 | { |
||
714 | return 0; |
||
715 | } |
||
716 | |||
717 | int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len) |
||
718 | { |
||
719 | pos = pos + 1; |
||
720 | |||
721 | if (pos > BUFNUM) pos = 1; |
||
722 | |||
723 | while (pl[pos].operand3 < pl[pos].operand2) _sleep2(125); |
||
724 | |||
725 | memcpy((char*)pl[pos].operand1, buf, len); |
||
726 | pl[pos].operand2 = len; |
||
727 | pl[pos].operand3 = 0; |
||
728 | |||
729 | return len; |
||
730 | } |
||
731 | |||
732 | int audio_close(struct audio_info_struct *ai) |
||
733 | { |
||
734 | ULONG rc; |
||
735 | |||
736 | pl[pos].operation = (ULONG)EXIT_OPERATION; |
||
737 | pl[pos].operand2 = 0; |
||
738 | pl[pos].operand3 = 0; |
||
739 | |||
740 | pos = pos - 1; |
||
741 | if(pos == 0) pos = BUFNUM; |
||
742 | |||
743 | while (pl[pos].operand3 < pl[pos].operand2) _sleep2(250); |
||
744 | _sleep2(2000); |
||
745 | |||
746 | rc = mciSendCommand(id, MCI_CLOSE, MCI_WAIT, (PVOID)NULL, 0); |
||
747 | return 0; |
||
748 | } |
||
749 | |||
750 | #else |
||
751 | |||
752 | int audio_open(struct audio_info_struct *ai) |
||
753 | { |
||
754 | fprintf(stderr,"No audio device support compiled into this binary (use -s).\n"); |
||
755 | return -1; |
||
756 | } |
||
757 | |||
758 | int audio_reset_parameters(struct audio_info_struct *ai) |
||
759 | { |
||
760 | return 0; |
||
761 | } |
||
762 | |||
763 | int audio_rate_best_match(struct audio_info_struct *ai) |
||
764 | { |
||
765 | return 0; |
||
766 | } |
||
767 | |||
768 | int audio_set_rate(struct audio_info_struct *ai) |
||
769 | { |
||
770 | return 0; |
||
771 | } |
||
772 | |||
773 | int audio_set_channels(struct audio_info_struct *ai) |
||
774 | { |
||
775 | return 0; |
||
776 | } |
||
777 | |||
778 | int audio_set_format(struct audio_info_struct *ai) |
||
779 | { |
||
780 | return 0; |
||
781 | } |
||
782 | |||
783 | int audio_get_formats(struct audio_info_struct *ai) |
||
784 | { |
||
785 | return AUDIO_FORMAT_SIGNED_16; |
||
786 | } |
||
787 | |||
788 | int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len) |
||
789 | { |
||
790 | return len; |
||
791 | } |
||
792 | |||
793 | int audio_close(struct audio_info_struct *ai) |
||
794 | { |
||
795 | return 0; |
||
796 | } |
||
797 | #endif |