2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
6 #include "oss_intern.h"
8 #include <hidd/unixio.h>
12 /* avoid conflicts between our __unused define and the ones that might come in
17 #include <sys/ioctl.h>
19 #include <sys/soundcard.h>
20 //#include <sys/mman.h>
22 /* Make it build on both newer and older OSS libraries */
23 #if !defined(SNDCTL_DSP_SPEED) && defined(SOUND_PCM_WRITE_RATE)
24 # define SNDCTL_DSP_SPEED SOUND_PCM_WRITE_RATE
27 #include <aros/debug.h>
29 /******************************************************************************/
31 BOOL
OSS_Open(char *filename
, BOOL read
, BOOL write
, BOOL blocking
)
35 if (!filename
) filename
= "/dev/dsp";
50 if (!blocking
) openflags
|= O_NONBLOCK
;
52 audio_fd
= Hidd_UnixIO_OpenFile(unixio
, filename
, openflags
, 0, NULL
);
54 return (audio_fd
>= 0) ? TRUE
: FALSE
;
57 /******************************************************************************/
63 Hidd_UnixIO_CloseFile(unixio
, audio_fd
, NULL
);
68 /******************************************************************************/
76 Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_RESET
, &value
, NULL
);
80 /******************************************************************************/
82 BOOL
OSS_SetFragmentSize(int num_fragments
, int fragment_size
)
89 value
= (num_fragments
<< 16) | fragment_size
;
91 retval
= Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_SETFRAGMENT
, &value
, NULL
);
92 return (retval
< 0) ? FALSE
: TRUE
;
100 /******************************************************************************/
102 BOOL
OSS_GetOutputInfo(int *num_fragments_available
, int *num_fragments_allocated
,
103 int *fragment_size
, int *num_bytes_available
)
110 Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_GETOSPACE
, &info
, NULL
);
112 if (num_fragments_available
) *num_fragments_available
= info
.fragments
;
113 if (num_fragments_allocated
) *num_fragments_allocated
= info
.fragstotal
;
114 if (fragment_size
) *fragment_size
= info
.fragsize
;
115 if (num_bytes_available
) *num_bytes_available
= info
.bytes
;
125 /******************************************************************************/
127 BOOL
OSS_GetOutputPointer(int *processed_bytes
, int *fragment_transitions
, int *dmapointer
)
133 Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_GETOPTR
, &info
, NULL
);
135 if (processed_bytes
) *processed_bytes
= info
.bytes
;
136 if (fragment_transitions
) *fragment_transitions
= info
.blocks
;
137 if (dmapointer
) *dmapointer
= info
.ptr
;
149 /******************************************************************************/
151 int audio_supported_fmts
;
153 static BOOL
get_supported_fmts(void)
155 if (audio_supported_fmts
) return TRUE
;
156 if (audio_fd
< 0) return FALSE
;
158 Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_GETFMTS
, &audio_supported_fmts
, NULL
);
164 /******************************************************************************/
166 BOOL
OSS_FormatSupported_S8(void)
168 if (!get_supported_fmts()) return FALSE
;
170 return (audio_supported_fmts
& AFMT_S8
) ? TRUE
: FALSE
;
173 /******************************************************************************/
175 BOOL
OSS_FormatSupported_U8(void)
177 if (!get_supported_fmts()) return FALSE
;
179 return (audio_supported_fmts
& AFMT_U8
) ? TRUE
: FALSE
;
182 /******************************************************************************/
184 BOOL
OSS_FormatSupported_S16LE(void)
186 if (!get_supported_fmts()) return FALSE
;
188 return (audio_supported_fmts
& AFMT_S16_LE
) ? TRUE
: FALSE
;
191 /******************************************************************************/
193 BOOL
OSS_FormatSupported_S16BE(void)
195 if (!get_supported_fmts()) return FALSE
;
197 return (audio_supported_fmts
& AFMT_S16_BE
) ? TRUE
: FALSE
;
200 /******************************************************************************/
202 BOOL
OSS_FormatSupported_U16LE(void)
204 if (!get_supported_fmts()) return FALSE
;
206 return (audio_supported_fmts
& AFMT_U16_LE
) ? TRUE
: FALSE
;
209 /******************************************************************************/
211 BOOL
OSS_FormatSupported_U16BE(void)
213 if (!get_supported_fmts()) return FALSE
;
215 return (audio_supported_fmts
& AFMT_U16_BE
) ? TRUE
: FALSE
;
218 /******************************************************************************/
220 int audio_capabilities
;
222 static BOOL
get_capabilities(void)
224 if (audio_capabilities
) return TRUE
;
225 if (audio_fd
< 0) return FALSE
;
227 Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_GETCAPS
, &audio_capabilities
, NULL
);
233 /******************************************************************************/
235 int OSS_Revision(void)
237 if (!get_capabilities()) return 0;
239 return audio_capabilities
& DSP_CAP_REVISION
;
242 /******************************************************************************/
244 BOOL
OSS_Capability_Duplex(void)
246 if (!get_capabilities()) return 0;
248 return (audio_capabilities
& DSP_CAP_DUPLEX
) ? TRUE
: FALSE
;
251 /******************************************************************************/
253 BOOL
OSS_Capability_Realtime(void)
255 if (!get_capabilities()) return 0;
257 return (audio_capabilities
& DSP_CAP_REALTIME
) ? TRUE
: FALSE
;
260 /******************************************************************************/
262 BOOL
OSS_Capability_Trigger(void)
264 if (!get_capabilities()) return 0;
266 return (audio_capabilities
& DSP_CAP_TRIGGER
) ? TRUE
: FALSE
;
269 /******************************************************************************/
271 BOOL
OSS_Capability_MMap(void)
273 if (!get_capabilities()) return 0;
275 return (audio_capabilities
& DSP_CAP_MMAP
) ? TRUE
: FALSE
;
278 /******************************************************************************/
280 static BOOL
set_format(int fmt
)
285 int retval
= Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_SETFMT
, &val
, NULL
);
287 if ((val
!= fmt
) || (retval
< 0))
301 /******************************************************************************/
303 BOOL
OSS_SetFormat_S8(void)
305 return set_format(AFMT_S8
);
308 /******************************************************************************/
310 BOOL
OSS_SetFormat_U8(void)
312 return set_format(AFMT_U8
);
315 /******************************************************************************/
317 BOOL
OSS_SetFormat_S16LE(void)
319 return set_format(AFMT_S16_LE
);
322 /******************************************************************************/
324 BOOL
OSS_SetFormat_S16BE(void)
326 return set_format(AFMT_S16_BE
);
329 /******************************************************************************/
331 BOOL
OSS_SetFormat_U16LE(void)
333 return set_format(AFMT_S16_LE
);
336 /******************************************************************************/
338 BOOL
OSS_SetFormat_U16BE(void)
340 return set_format(AFMT_S16_BE
);
343 /******************************************************************************/
345 BOOL
OSS_SetMono(void)
350 if (audio_fd
< 0) return FALSE
;
352 retval
= Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_STEREO
, &val
, NULL
);
354 if ((retval
< 0) || (val
!= 0)) return FALSE
;
359 /******************************************************************************/
361 BOOL
OSS_SetStereo(void)
366 if (audio_fd
< 0) return FALSE
;
368 retval
= Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_STEREO
, &val
, NULL
);
370 if ((retval
< 0) || (val
!= 1)) return FALSE
;
375 /******************************************************************************/
377 BOOL
OSS_SetNumChannels(int numchannels
)
379 int val
= numchannels
;
382 if (audio_fd
< 0) return FALSE
;
384 retval
= Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_CHANNELS
, &val
, NULL
);
387 return (numchannels
> 1) ? OSS_SetStereo() : OSS_SetMono();
393 /******************************************************************************/
395 BOOL
OSS_SetWriteRate(int rate
, int *used_rate
)
400 if (audio_fd
< 0) return FALSE
;
402 retval
= Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_SPEED
, &val
, NULL
);
408 if (used_rate
) *used_rate
= val
;
413 /******************************************************************************/
415 BOOL
OSS_MMap(APTR
*mapped_address
, int len
, BOOL read
, BOOL write
)
418 /* FIXME: Can't use mmap yet! */
419 kprintf("\n=== Dont' call OSS_MMap! Not implemented yet! ===\n\n");
425 if (audio_fd
< 0) return FALSE
;
429 protection
= PROT_READ
| PROT_WRITE
;
433 protection
= PROT_READ
;
437 protection
= PROT_WRITE
;
440 buf
= (APTR
)mmap(NULL
, len
, protection
, MAP_SHARED
, audio_fd
, 0);
441 if (buf
== MAP_FAILED
)
446 *mapped_address
= buf
;
453 /******************************************************************************/
455 void OSS_MUnmap(APTR mapped_address
, int len
)
458 /* FIXME: Can't use munmap yet! */
459 kprintf("\n=== Dont' call OSS_MUnmap! Not implemented yet! ===\n\n");
461 if ((audio_fd
>= 0) && (mapped_address
!= MAP_FAILED
))
463 munmap(mapped_address
, len
);
468 /******************************************************************************/
470 BOOL
OSS_SetTrigger(BOOL input
, BOOL output
)
475 if (audio_fd
< 0) return FALSE
;
477 if (input
) val
|= PCM_ENABLE_INPUT
;
478 if (output
) val
|= PCM_ENABLE_OUTPUT
;
480 retval
= Hidd_UnixIO_IOControlFile(unixio
, audio_fd
, SNDCTL_DSP_SETTRIGGER
, &val
, NULL
);
482 return (retval
< 0) ? FALSE
: TRUE
;
485 /******************************************************************************/
487 int OSS_Write(APTR buf
, int size
)
497 written
= Hidd_UnixIO_WriteFile(unixio
, audio_fd
, buf
, size
, &Errno
);
503 written
= -2; /* Retval -2. Caller should treat it like EAGAIN. */
507 written
= -3; /* Retval -3. Caller should treat it like EINTR. */
511 written
= -4; /* Retval -4. Caller should treat it like a 0-Errno.
512 (but since retval of write() was -1, like EAGAIN
522 /******************************************************************************/