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_audiomem.h" 44 #include "../SDL_audio_c.h" 45 #include "../SDL_audiodev_c.h" 50 #if defined(AUDIO_GETINFO) && !defined(AUDIO_GETBUFINFO) 51 #define AUDIO_GETBUFINFO AUDIO_GETINFO 55 static Uint8 snd2au(
int sample);
59 SUNAUDIO_DetectDevices(
void)
68 #ifdef AUDIO_GETBUFINFO 72 ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info);
73 left = (this->hidden->written - info.play.samples);
74 if (this->hidden->written && (left == 0)) {
75 fprintf(stderr,
"audio underflow!\n");
82 SUNAUDIO_WaitDevice(
_THIS)
84 #ifdef AUDIO_GETBUFINFO 85 #define SLEEP_FUDGE 10 89 ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info);
90 left = (this->hidden->written - info.play.samples);
91 if (left > this->hidden->fragsize) {
94 sleepy = ((left - this->hidden->fragsize) / this->hidden->frequency);
95 sleepy -= SLEEP_FUDGE;
104 FD_SET(this->hidden->audio_fd, &fdset);
105 select(this->hidden->audio_fd + 1,
NULL, &fdset,
NULL,
NULL);
110 SUNAUDIO_PlayDevice(
_THIS)
113 if (this->hidden->ulaw_only) {
115 int accum, incr, pos;
120 aubuf = this->hidden->ulaw_buf;
121 switch (this->hidden->audio_fmt & 0xFF) {
126 sndbuf = this->hidden->mixbuf;
127 for (pos = 0; pos < this->hidden->fragsize; ++pos) {
128 *aubuf = snd2au((0x80 - *sndbuf) * 64);
142 sndbuf = (
Sint16 *) this->hidden->mixbuf;
143 for (pos = 0; pos < this->hidden->fragsize; ++pos) {
144 *aubuf = snd2au(*sndbuf / 4);
156 CheckUnderflow(
this);
158 if (write(this->hidden->audio_fd, this->hidden->ulaw_buf,
159 this->hidden->fragsize) < 0) {
163 this->hidden->written += this->hidden->fragsize;
166 CheckUnderflow(
this);
168 if (write(this->hidden->audio_fd, this->hidden->mixbuf,
169 this->spec.size) < 0) {
173 this->hidden->written += this->hidden->fragsize;
178 SUNAUDIO_GetDeviceBuf(
_THIS)
180 return (this->hidden->mixbuf);
184 SUNAUDIO_CloseDevice(
_THIS)
186 if (this->hidden !=
NULL) {
188 this->hidden->mixbuf =
NULL;
190 this->hidden->ulaw_buf =
NULL;
191 if (this->hidden->audio_fd >= 0) {
192 close(this->hidden->audio_fd);
193 this->hidden->audio_fd = -1;
201 SUNAUDIO_OpenDevice(
_THIS,
void *handle,
const char *devname,
int iscapture)
209 if (devname ==
NULL) {
211 if (devname ==
NULL) {
219 if (this->hidden ==
NULL) {
222 SDL_memset(this->hidden, 0, (
sizeof *this->hidden));
225 this->hidden->audio_fd = open(devname, flags, 0);
226 if (this->hidden->audio_fd < 0) {
227 return SDL_SetError(
"Couldn't open %s: %s", devname, strerror(errno));
242 enc = AUDIO_ENCODING_LINEAR8;
251 enc = AUDIO_ENCODING_LINEAR;
264 this->hidden->ulaw_only = 0;
268 AUDIO_INITINFO(&info);
271 info.play.sample_rate = this->
spec.
freq;
273 info.play.precision = (enc == AUDIO_ENCODING_ULAW)
275 info.play.encoding = enc;
276 if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
279 if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
280 return SDL_SetError(
"Error getting audio parameters: %s",
283 if (info.play.encoding == enc
284 && info.play.precision == (this->spec.format & 0xff)
285 && info.play.channels == this->spec.channels) {
287 this->
spec.
freq = info.play.sample_rate;
293 case AUDIO_ENCODING_LINEAR8:
295 enc = AUDIO_ENCODING_LINEAR;
299 case AUDIO_ENCODING_LINEAR:
301 enc = AUDIO_ENCODING_ULAW;
305 this->hidden->ulaw_only = 1;
310 return SDL_SetError(
"Error setting audio parameters: %s",
315 this->hidden->written = 0;
318 if (this->hidden->ulaw_only) {
320 this->hidden->fragsize = (this->
spec.
samples * 1000) /
322 this->hidden->frequency = 8;
324 if (this->hidden->ulaw_buf ==
NULL) {
330 this->hidden->frequency = this->
spec.
freq / 1000;
333 fprintf(stderr,
"Audio device %s U-Law only\n",
334 this->hidden->ulaw_only ?
"is" :
"is not");
335 fprintf(stderr,
"format=0x%x chan=%d freq=%d\n",
336 this->
spec.
format, this->spec.channels, this->spec.freq);
344 if (this->hidden->mixbuf ==
NULL) {
347 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
385 sample = 0xF0 | (15 - sample / 2);
386 }
else if (sample < 96) {
387 sample = 0xE0 | (15 - (sample - 32) / 4);
388 }
else if (sample < 224) {
389 sample = 0xD0 | (15 - (sample - 96) / 8);
390 }
else if (sample < 480) {
391 sample = 0xC0 | (15 - (sample - 224) / 16);
392 }
else if (sample < 992) {
393 sample = 0xB0 | (15 - (sample - 480) / 32);
394 }
else if (sample < 2016) {
395 sample = 0xA0 | (15 - (sample - 992) / 64);
396 }
else if (sample < 4064) {
397 sample = 0x90 | (15 - (sample - 2016) / 128);
398 }
else if (sample < 8160) {
399 sample = 0x80 | (15 - (sample - 4064) / 256);
403 return (mask & sample);
423 "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)
#define SDL_AllocAudioMem
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.