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 "../../core/unix/SDL_poll.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;
106 SUNAUDIO_PlayDevice(
_THIS)
109 if (this->hidden->ulaw_only) {
111 int accum, incr, pos;
116 aubuf = this->hidden->ulaw_buf;
117 switch (this->hidden->audio_fmt & 0xFF) {
122 sndbuf = this->hidden->mixbuf;
123 for (pos = 0; pos < this->hidden->fragsize; ++pos) {
124 *aubuf = snd2au((0x80 - *sndbuf) * 64);
138 sndbuf = (
Sint16 *) this->hidden->mixbuf;
139 for (pos = 0; pos < this->hidden->fragsize; ++pos) {
140 *aubuf = snd2au(*sndbuf / 4);
152 CheckUnderflow(
this);
154 if (write(this->hidden->audio_fd, this->hidden->ulaw_buf,
155 this->hidden->fragsize) < 0) {
159 this->hidden->written += this->hidden->fragsize;
162 CheckUnderflow(
this);
164 if (write(this->hidden->audio_fd, this->hidden->mixbuf,
165 this->spec.size) < 0) {
169 this->hidden->written += this->hidden->fragsize;
174 SUNAUDIO_GetDeviceBuf(
_THIS)
176 return (this->hidden->mixbuf);
180 SUNAUDIO_CloseDevice(
_THIS)
183 if (this->hidden->audio_fd >= 0) {
184 close(this->hidden->audio_fd);
191 SUNAUDIO_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
196 int desired_freq = 0;
203 if (devname ==
NULL) {
205 if (devname ==
NULL) {
213 if (this->hidden ==
NULL) {
219 this->hidden->audio_fd = open(devname, flags, 0);
220 if (this->hidden->audio_fd < 0) {
221 return SDL_SetError(
"Couldn't open %s: %s", devname, strerror(errno));
233 enc = AUDIO_ENCODING_LINEAR8;
242 enc = AUDIO_ENCODING_LINEAR;
255 this->hidden->ulaw_only = 0;
259 AUDIO_INITINFO(&info);
262 info.play.sample_rate = this->
spec.
freq;
264 info.play.precision = (enc == AUDIO_ENCODING_ULAW)
266 info.play.encoding = enc;
267 if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
270 if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
271 return SDL_SetError(
"Error getting audio parameters: %s",
274 if (info.play.encoding == enc
275 && info.play.precision == (this->spec.format & 0xff)
276 && info.play.channels == this->spec.channels) {
278 this->
spec.
freq = info.play.sample_rate;
284 case AUDIO_ENCODING_LINEAR8:
286 enc = AUDIO_ENCODING_LINEAR;
290 case AUDIO_ENCODING_LINEAR:
292 enc = AUDIO_ENCODING_ULAW;
296 this->hidden->ulaw_only = 1;
301 return SDL_SetError(
"Error setting audio parameters: %s",
306 this->hidden->written = 0;
309 if (this->hidden->ulaw_only) {
311 this->hidden->fragsize = (this->
spec.
samples * 1000) /
313 this->hidden->frequency = 8;
315 if (this->hidden->ulaw_buf ==
NULL) {
321 this->hidden->frequency = this->
spec.
freq / 1000;
324 fprintf(stderr,
"Audio device %s U-Law only\n",
325 this->hidden->ulaw_only ?
"is" :
"is not");
326 fprintf(stderr,
"format=0x%x chan=%d freq=%d\n",
327 this->
spec.
format, this->spec.channels, this->spec.freq);
335 if (this->hidden->mixbuf ==
NULL) {
338 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
376 sample = 0xF0 | (15 - sample / 2);
377 }
else if (sample < 96) {
378 sample = 0xE0 | (15 - (sample - 32) / 4);
379 }
else if (sample < 224) {
380 sample = 0xD0 | (15 - (sample - 96) / 8);
381 }
else if (sample < 480) {
382 sample = 0xC0 | (15 - (sample - 224) / 16);
383 }
else if (sample < 992) {
384 sample = 0xB0 | (15 - (sample - 480) / 32);
385 }
else if (sample < 2016) {
386 sample = 0xA0 | (15 - (sample - 992) / 64);
387 }
else if (sample < 4064) {
388 sample = 0x90 | (15 - (sample - 2016) / 128);
389 }
else if (sample < 8160) {
390 sample = 0x80 | (15 - (sample - 4064) / 256);
394 return (mask & sample);
414 "audio",
"UNIX /dev/audio interface", SUNAUDIO_Init, 0
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
void(* DetectDevices)(void)
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
Uint16 SDL_AudioFormat
Audio format flags.
AudioBootStrap SUNAUDIO_bootstrap
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define SDL_GetAudioDeviceName
void SDL_EnumUnixAudioDevices(const int classic, int(*test)(int))
EGLImageKHR EGLint EGLint * handle
#define OPEN_FLAGS_OUTPUT
#define SDL_AUDIO_BITSIZE(x)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_OutOfMemory()
void(* CloseDevice)(_THIS)
int AllowsArbitraryDeviceNames
Uint8 *(* GetDeviceBuf)(_THIS)