23 #if SDL_AUDIO_DRIVER_PAUDIO
31 #include <sys/ioctl.h>
37 #include "SDL_stdinc.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) {
143 audio_buffer paud_bufinfo;
148 FD_SET(this->hidden->audio_fd, &fdset);
150 if (ioctl(this->hidden->audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
152 fprintf(stderr,
"Couldn't get audio buffer information\n");
157 long ms_in_buf = paud_bufinfo.write_buf_time;
158 timeout.tv_sec = ms_in_buf / 1000;
159 ms_in_buf = ms_in_buf -
timeout.tv_sec * 1000;
160 timeout.tv_usec = ms_in_buf * 1000;
163 "Waiting for write_buf_time=%ld,%ld\n",
169 fprintf(stderr,
"Waiting for audio to get ready\n");
174 "Audio timeout - buggy audio driver? (disabled)";
180 fprintf(stderr,
"SDL: %s - %s\n", strerror(errno), message);
183 this->hidden->audio_fd = -1;
185 fprintf(stderr,
"Done disabling audio\n");
189 fprintf(stderr,
"Ready!\n");
195 PAUDIO_PlayDevice(
_THIS)
198 const Uint8 *mixbuf = this->hidden->mixbuf;
199 const size_t mixlen = this->hidden->mixlen;
203 written = write(this->hidden->audio_fd, mixbuf, mixlen);
204 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) {
207 }
while ((written < 0) &&
208 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)));
211 if (this->hidden->frame_ticks) {
212 this->hidden->next_frame += this->hidden->frame_ticks;
220 fprintf(stderr,
"Wrote %d bytes of audio data\n", written);
225 PAUDIO_GetDeviceBuf(
_THIS)
227 return this->hidden->mixbuf;
231 PAUDIO_CloseDevice(
_THIS)
233 if (this->hidden !=
NULL) {
235 this->hidden->mixbuf =
NULL;
236 if (this->hidden->audio_fd >= 0) {
237 close(this->hidden->audio_fd);
238 this->hidden->audio_fd = -1;
246 PAUDIO_OpenDevice(
_THIS,
const char *devname,
int iscapture)
248 const char *workaround =
SDL_getenv(
"SDL_DSP_NOSELECT");
250 const char *err =
NULL;
252 int bytes_per_sample;
254 audio_init paud_init;
255 audio_buffer paud_bufinfo;
256 audio_status paud_status;
257 audio_control paud_control;
258 audio_change paud_change;
264 if (this->hidden ==
NULL) {
267 SDL_memset(this->hidden, 0, (
sizeof *this->hidden));
270 fd = OpenAudioPath(audiodev,
sizeof(audiodev), OPEN_FLAGS, 0);
271 this->hidden->audio_fd = fd;
273 PAUDIO_CloseDevice(
this);
274 return SDL_SetError(
"Couldn't open %s: %s", audiodev, strerror(errno));
281 if (ioctl(fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
282 PAUDIO_CloseDevice(
this);
283 return SDL_SetError(
"Couldn't get audio buffer information");
286 if (this->spec.channels > 1)
287 this->spec.channels = 2;
289 this->spec.channels = 1;
336 paud_init.srate = this->spec.freq;
337 paud_init.mode = PCM;
338 paud_init.operation = PLAY;
339 paud_init.channels = this->spec.channels;
344 !format && test_format;) {
346 fprintf(stderr,
"Trying format 0x%4.4x\n", test_format);
348 switch (test_format) {
350 bytes_per_sample = 1;
351 paud_init.bits_per_sample = 8;
352 paud_init.flags = TWOS_COMPLEMENT | FIXED;
356 bytes_per_sample = 1;
357 paud_init.bits_per_sample = 8;
358 paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
362 bytes_per_sample = 2;
363 paud_init.bits_per_sample = 16;
364 paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
368 bytes_per_sample = 2;
369 paud_init.bits_per_sample = 16;
370 paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
374 bytes_per_sample = 2;
375 paud_init.bits_per_sample = 16;
376 paud_init.flags = TWOS_COMPLEMENT | FIXED;
380 bytes_per_sample = 2;
381 paud_init.bits_per_sample = 16;
382 paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
394 fprintf(stderr,
"Couldn't find any hardware audio formats\n");
396 PAUDIO_CloseDevice(
this);
397 return SDL_SetError(
"Couldn't find any hardware audio formats");
399 this->spec.format = test_format;
411 if (paud_bufinfo.request_buf_cap == 1) {
412 this->spec.samples = paud_bufinfo.write_buf_cap
413 / bytes_per_sample / this->spec.channels;
415 this->spec.samples = paud_bufinfo.write_buf_cap
416 / bytes_per_sample / this->spec.channels / 2;
418 paud_init.bsize = bytes_per_sample * this->spec.channels;
430 if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) {
431 switch (paud_init.rc) {
433 err =
"Couldn't set audio format: DSP can't do play requests";
436 err =
"Couldn't set audio format: DSP can't do record requests";
439 err =
"Couldn't set audio format: request was invalid";
442 err =
"Couldn't set audio format: conflict with open's flags";
445 err =
"Couldn't set audio format: out of DSP MIPS or memory";
448 err =
"Couldn't set audio format: not documented in sys/audio.h";
454 PAUDIO_CloseDevice(
this);
459 this->hidden->mixlen = this->spec.size;
461 if (this->hidden->mixbuf ==
NULL) {
462 PAUDIO_CloseDevice(
this);
465 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
471 paud_change.input = AUDIO_IGNORE;
472 paud_change.output = OUTPUT_1;
473 paud_change.monitor = AUDIO_IGNORE;
474 paud_change.volume = 0x7fffffff;
475 paud_change.volume_delay = AUDIO_IGNORE;
476 paud_change.balance = 0x3fffffff;
477 paud_change.balance_delay = AUDIO_IGNORE;
478 paud_change.treble = AUDIO_IGNORE;
479 paud_change.bass = AUDIO_IGNORE;
480 paud_change.pitch = AUDIO_IGNORE;
482 paud_control.ioctl_request = AUDIO_CHANGE;
483 paud_control.request_info = (
char *) &paud_change;
484 if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
486 fprintf(stderr,
"Can't change audio display settings\n");
494 paud_control.ioctl_request = AUDIO_START;
495 paud_control.position = 0;
496 if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
497 PAUDIO_CloseDevice(
this);
499 fprintf(stderr,
"Can't start audio play\n");
505 if (workaround !=
NULL) {
506 this->hidden->frame_ticks = (float) (this->spec.samples * 1000) /
508 this->hidden->next_frame =
SDL_GetTicks() + this->hidden->frame_ticks;
519 int fd = OpenAudioPath(
NULL, 0, OPEN_FLAGS, 0);
538 "paud",
"AIX Paudio", PAUDIO_Init, 0
void(* CloseDevice)(_THIS)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
int32_t Sint32
A signed 32-bit integer type.
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
GLenum GLsizei const GLuint GLboolean enabled
Uint8 *(* GetDeviceBuf)(_THIS)
DECLSPEC void SDLCALL SDL_free(void *mem)
Uint16 SDL_AudioFormat
Audio format flags.
int(* OpenDevice)(_THIS, const char *devname, int iscapture)
GLsizei const GLchar *const * path
SDL_AudioFormat SDL_NextAudioFormat(void)
void(* PlayDevice)(_THIS)
DECLSPEC Uint32 SDLCALL SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
int OnlyHasDefaultOutputDevice
AudioBootStrap PAUDIO_bootstrap
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
DECLSPEC void SDLCALL SDL_Delay(Uint32 ms)
Wait a specified number of milliseconds before returning.
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
#define SDL_AllocAudioMem
GLbitfield GLuint64 timeout
#define SDL_OutOfMemory()
#define SDL_arraysize(array)
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
uint8_t Uint8
An unsigned 8-bit integer type.
DECLSPEC char *SDLCALL SDL_getenv(const char *name)