21 #include "../../SDL_internal.h" 23 #if SDL_AUDIO_DRIVER_PAUDIO 31 #include <sys/ioctl.h> 32 #include <sys/types.h> 38 #include "../SDL_audiomem.h" 39 #include "../SDL_audio_c.h" 46 #include <sys/machine.h> 48 #include <sys/audio.h> 52 #define OPEN_FLAGS O_WRONLY 57 #define _PATH_DEV_DSP "/dev/%caud%c/%c" 60 static char devsettings[][3] = {
61 {
'p',
'0',
'1'}, {
'p',
'0',
'2'}, {
'p',
'0',
'3'}, {
'p',
'0',
'4'},
62 {
'p',
'1',
'1'}, {
'p',
'1',
'2'}, {
'p',
'1',
'3'}, {
'p',
'1',
'4'},
63 {
'p',
'2',
'1'}, {
'p',
'2',
'2'}, {
'p',
'2',
'3'}, {
'p',
'2',
'4'},
64 {
'p',
'3',
'1'}, {
'p',
'3',
'2'}, {
'p',
'3',
'3'}, {
'p',
'3',
'4'},
65 {
'b',
'0',
'1'}, {
'b',
'0',
'2'}, {
'b',
'0',
'3'}, {
'b',
'0',
'4'},
66 {
'b',
'1',
'1'}, {
'b',
'1',
'2'}, {
'b',
'1',
'3'}, {
'b',
'1',
'4'},
67 {
'b',
'2',
'1'}, {
'b',
'2',
'2'}, {
'b',
'2',
'3'}, {
'b',
'2',
'4'},
68 {
'b',
'3',
'1'}, {
'b',
'3',
'2'}, {
'b',
'3',
'3'}, {
'b',
'3',
'4'},
73 OpenUserDefinedDevice(
char *
path,
int maxlen,
int flags)
82 if (audiodev ==
NULL) {
85 fd = open(audiodev, flags, 0);
88 path[maxlen - 1] =
'\0';
94 OpenAudioPath(
char *path,
int maxlen,
int flags,
int classic)
98 int fd = OpenUserDefinedDevice(path, maxlen, flags);
105 while (devsettings[cycle][0] !=
'\0') {
106 char audiopath[1024];
109 devsettings[cycle][0],
110 devsettings[cycle][1], devsettings[cycle][2]);
112 if (stat(audiopath, &sb) == 0) {
113 fd = open(audiopath, flags, 0);
127 PAUDIO_WaitDevice(
_THIS)
132 if (this->hidden->frame_ticks) {
141 audio_buffer paud_bufinfo;
146 FD_SET(this->hidden->audio_fd, &fdset);
148 if (ioctl(this->hidden->audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
150 fprintf(stderr,
"Couldn't get audio buffer information\n");
155 long ms_in_buf = paud_bufinfo.write_buf_time;
156 timeout.tv_sec = ms_in_buf / 1000;
157 ms_in_buf = ms_in_buf -
timeout.tv_sec * 1000;
158 timeout.tv_usec = ms_in_buf * 1000;
161 "Waiting for write_buf_time=%ld,%ld\n",
167 fprintf(stderr,
"Waiting for audio to get ready\n");
172 "Audio timeout - buggy audio driver? (disabled)";
178 fprintf(stderr,
"SDL: %s - %s\n", strerror(errno), message);
181 this->hidden->audio_fd = -1;
183 fprintf(stderr,
"Done disabling audio\n");
187 fprintf(stderr,
"Ready!\n");
193 PAUDIO_PlayDevice(
_THIS)
196 const Uint8 *mixbuf = this->hidden->mixbuf;
197 const size_t mixlen = this->hidden->mixlen;
201 written = write(this->hidden->audio_fd, mixbuf, mixlen);
202 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) {
205 }
while ((written < 0) &&
206 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)));
209 if (this->hidden->frame_ticks) {
210 this->hidden->next_frame += this->hidden->frame_ticks;
218 fprintf(stderr,
"Wrote %d bytes of audio data\n", written);
223 PAUDIO_GetDeviceBuf(
_THIS)
225 return this->hidden->mixbuf;
229 PAUDIO_CloseDevice(
_THIS)
231 if (this->hidden !=
NULL) {
233 this->hidden->mixbuf =
NULL;
234 if (this->hidden->audio_fd >= 0) {
235 close(this->hidden->audio_fd);
236 this->hidden->audio_fd = -1;
244 PAUDIO_OpenDevice(
_THIS,
void *handle,
const char *devname,
int iscapture)
246 const char *workaround =
SDL_getenv(
"SDL_DSP_NOSELECT");
248 const char *err =
NULL;
250 int bytes_per_sample;
252 audio_init paud_init;
253 audio_buffer paud_bufinfo;
254 audio_status paud_status;
255 audio_control paud_control;
256 audio_change paud_change;
262 if (this->hidden ==
NULL) {
265 SDL_memset(this->hidden, 0, (
sizeof *this->hidden));
268 fd = OpenAudioPath(audiodev,
sizeof(audiodev), OPEN_FLAGS, 0);
269 this->hidden->audio_fd = fd;
271 PAUDIO_CloseDevice(
this);
272 return SDL_SetError(
"Couldn't open %s: %s", audiodev, strerror(errno));
279 if (ioctl(fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
280 PAUDIO_CloseDevice(
this);
281 return SDL_SetError(
"Couldn't get audio buffer information");
335 paud_init.mode = PCM;
336 paud_init.operation = PLAY;
342 !format && test_format;) {
344 fprintf(stderr,
"Trying format 0x%4.4x\n", test_format);
346 switch (test_format) {
348 bytes_per_sample = 1;
349 paud_init.bits_per_sample = 8;
350 paud_init.flags = TWOS_COMPLEMENT | FIXED;
354 bytes_per_sample = 1;
355 paud_init.bits_per_sample = 8;
356 paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
360 bytes_per_sample = 2;
361 paud_init.bits_per_sample = 16;
362 paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
366 bytes_per_sample = 2;
367 paud_init.bits_per_sample = 16;
368 paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
372 bytes_per_sample = 2;
373 paud_init.bits_per_sample = 16;
374 paud_init.flags = TWOS_COMPLEMENT | FIXED;
378 bytes_per_sample = 2;
379 paud_init.bits_per_sample = 16;
380 paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
392 fprintf(stderr,
"Couldn't find any hardware audio formats\n");
394 PAUDIO_CloseDevice(
this);
395 return SDL_SetError(
"Couldn't find any hardware audio formats");
409 if (paud_bufinfo.request_buf_cap == 1) {
416 paud_init.bsize = bytes_per_sample * this->
spec.
channels;
428 if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) {
429 switch (paud_init.rc) {
431 err =
"Couldn't set audio format: DSP can't do play requests";
434 err =
"Couldn't set audio format: DSP can't do record requests";
437 err =
"Couldn't set audio format: request was invalid";
440 err =
"Couldn't set audio format: conflict with open's flags";
443 err =
"Couldn't set audio format: out of DSP MIPS or memory";
446 err =
"Couldn't set audio format: not documented in sys/audio.h";
452 PAUDIO_CloseDevice(
this);
457 this->hidden->mixlen = this->
spec.
size;
459 if (this->hidden->mixbuf ==
NULL) {
460 PAUDIO_CloseDevice(
this);
463 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
469 paud_change.input = AUDIO_IGNORE;
470 paud_change.output = OUTPUT_1;
471 paud_change.monitor = AUDIO_IGNORE;
472 paud_change.volume = 0x7fffffff;
473 paud_change.volume_delay = AUDIO_IGNORE;
474 paud_change.balance = 0x3fffffff;
475 paud_change.balance_delay = AUDIO_IGNORE;
476 paud_change.treble = AUDIO_IGNORE;
477 paud_change.bass = AUDIO_IGNORE;
478 paud_change.pitch = AUDIO_IGNORE;
480 paud_control.ioctl_request = AUDIO_CHANGE;
481 paud_control.request_info = (
char *) &paud_change;
482 if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
484 fprintf(stderr,
"Can't change audio display settings\n");
492 paud_control.ioctl_request = AUDIO_START;
493 paud_control.position = 0;
494 if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
495 PAUDIO_CloseDevice(
this);
497 fprintf(stderr,
"Can't start audio play\n");
503 if (workaround !=
NULL) {
504 this->hidden->frame_ticks = (float) (this->
spec.
samples * 1000) /
506 this->hidden->next_frame =
SDL_GetTicks() + this->hidden->frame_ticks;
517 int fd = OpenAudioPath(
NULL, 0, OPEN_FLAGS, 0);
536 "paud",
"AIX Paudio", PAUDIO_Init, 0
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
GLuint GLsizei const GLchar * message
void(* PlayDevice)(_THIS)
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
Uint16 SDL_AudioFormat
Audio format flags.
SDL_AudioFormat SDL_NextAudioFormat(void)
int OnlyHasDefaultOutputDevice
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
uint8_t Uint8
An unsigned 8-bit integer type.
AudioBootStrap PAUDIO_bootstrap
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)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
GLbitfield GLuint64 timeout
Uint8 *(* GetDeviceBuf)(_THIS)
#define SDL_arraysize(array)
GLsizei const GLchar *const * path