21 #include "../../SDL_internal.h" 23 #if SDL_AUDIO_DRIVER_SUNAUDIO 30 #include <sys/ioctl.h> 31 #include <sys/audioio.h> 34 #include <sys/audioio.h> 37 #include <sys/types.h> 43 #include "../SDL_audio_c.h" 44 #include "../SDL_audiodev_c.h" 49 #if defined(AUDIO_GETINFO) && !defined(AUDIO_GETBUFINFO) 50 #define AUDIO_GETBUFINFO AUDIO_GETINFO 54 static Uint8 snd2au(
int sample);
58 SUNAUDIO_DetectDevices(
void)
67 #ifdef AUDIO_GETBUFINFO 71 ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info);
72 left = (this->hidden->written - info.play.samples);
73 if (this->hidden->written && (left == 0)) {
74 fprintf(stderr,
"audio underflow!\n");
81 SUNAUDIO_WaitDevice(
_THIS)
83 #ifdef AUDIO_GETBUFINFO 84 #define SLEEP_FUDGE 10 88 ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info);
89 left = (this->hidden->written - info.play.samples);
90 if (left > this->hidden->fragsize) {
93 sleepy = ((left - this->hidden->fragsize) / this->hidden->frequency);
94 sleepy -= SLEEP_FUDGE;
103 FD_SET(this->hidden->audio_fd, &fdset);
104 select(this->hidden->audio_fd + 1,
NULL, &fdset,
NULL,
NULL);
109 SUNAUDIO_PlayDevice(
_THIS)
112 if (this->hidden->ulaw_only) {
114 int accum, incr, pos;
119 aubuf = this->hidden->ulaw_buf;
120 switch (this->hidden->audio_fmt & 0xFF) {
125 sndbuf = this->hidden->mixbuf;
126 for (pos = 0; pos < this->hidden->fragsize; ++pos) {
127 *aubuf = snd2au((0x80 - *sndbuf) * 64);
141 sndbuf = (
Sint16 *) this->hidden->mixbuf;
142 for (pos = 0; pos < this->hidden->fragsize; ++pos) {
143 *aubuf = snd2au(*sndbuf / 4);
155 CheckUnderflow(
this);
157 if (write(this->hidden->audio_fd, this->hidden->ulaw_buf,
158 this->hidden->fragsize) < 0) {
162 this->hidden->written += this->hidden->fragsize;
165 CheckUnderflow(
this);
167 if (write(this->hidden->audio_fd, this->hidden->mixbuf,
168 this->spec.size) < 0) {
172 this->hidden->written += this->hidden->fragsize;
177 SUNAUDIO_GetDeviceBuf(
_THIS)
179 return (this->hidden->mixbuf);
183 SUNAUDIO_CloseDevice(
_THIS)
186 if (this->hidden->audio_fd >= 0) {
187 close(this->hidden->audio_fd);
194 SUNAUDIO_OpenDevice(
_THIS,
void *handle,
const char *devname,
int iscapture)
202 if (devname ==
NULL) {
204 if (devname ==
NULL) {
212 if (this->hidden ==
NULL) {
218 this->hidden->audio_fd = open(devname, flags, 0);
219 if (this->hidden->audio_fd < 0) {
220 return SDL_SetError(
"Couldn't open %s: %s", devname, strerror(errno));
235 enc = AUDIO_ENCODING_LINEAR8;
244 enc = AUDIO_ENCODING_LINEAR;
257 this->hidden->ulaw_only = 0;
261 AUDIO_INITINFO(&info);
264 info.play.sample_rate = this->
spec.
freq;
266 info.play.precision = (enc == AUDIO_ENCODING_ULAW)
268 info.play.encoding = enc;
269 if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
272 if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
273 return SDL_SetError(
"Error getting audio parameters: %s",
276 if (info.play.encoding == enc
277 && info.play.precision == (this->spec.format & 0xff)
278 && info.play.channels == this->spec.channels) {
280 this->
spec.
freq = info.play.sample_rate;
286 case AUDIO_ENCODING_LINEAR8:
288 enc = AUDIO_ENCODING_LINEAR;
292 case AUDIO_ENCODING_LINEAR:
294 enc = AUDIO_ENCODING_ULAW;
298 this->hidden->ulaw_only = 1;
303 return SDL_SetError(
"Error setting audio parameters: %s",
308 this->hidden->written = 0;
311 if (this->hidden->ulaw_only) {
313 this->hidden->fragsize = (this->
spec.
samples * 1000) /
315 this->hidden->frequency = 8;
317 if (this->hidden->ulaw_buf ==
NULL) {
323 this->hidden->frequency = this->
spec.
freq / 1000;
326 fprintf(stderr,
"Audio device %s U-Law only\n",
327 this->hidden->ulaw_only ?
"is" :
"is not");
328 fprintf(stderr,
"format=0x%x chan=%d freq=%d\n",
329 this->
spec.
format, this->spec.channels, this->spec.freq);
337 if (this->hidden->mixbuf ==
NULL) {
340 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
378 sample = 0xF0 | (15 - sample / 2);
379 }
else if (sample < 96) {
380 sample = 0xE0 | (15 - (sample - 32) / 4);
381 }
else if (sample < 224) {
382 sample = 0xD0 | (15 - (sample - 96) / 8);
383 }
else if (sample < 480) {
384 sample = 0xC0 | (15 - (sample - 224) / 16);
385 }
else if (sample < 992) {
386 sample = 0xB0 | (15 - (sample - 480) / 32);
387 }
else if (sample < 2016) {
388 sample = 0xA0 | (15 - (sample - 992) / 64);
389 }
else if (sample < 4064) {
390 sample = 0x90 | (15 - (sample - 2016) / 128);
391 }
else if (sample < 8160) {
392 sample = 0x80 | (15 - (sample - 4064) / 256);
396 return (mask & sample);
416 "audio",
"UNIX /dev/audio interface", SUNAUDIO_Init, 0
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
AudioBootStrap SUNAUDIO_bootstrap
void(* DetectDevices)(void)
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
Uint16 SDL_AudioFormat
Audio format flags.
#define SDL_GetAudioDeviceName
void SDL_EnumUnixAudioDevices(const int classic, int(*test)(int))
#define OPEN_FLAGS_OUTPUT
uint8_t Uint8
An unsigned 8-bit integer type.
#define SDL_AUDIO_BITSIZE(x)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
int32_t Sint32
A signed 32-bit integer type.
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_OutOfMemory()
void(* CloseDevice)(_THIS)
int AllowsArbitraryDeviceNames
Uint8 *(* GetDeviceBuf)(_THIS)
int16_t Sint16
A signed 16-bit integer type.