23 #if SDL_AUDIO_DRIVER_OSS
34 #include <sys/ioctl.h>
37 #if SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H
39 #include <soundcard.h>
42 #include <sys/soundcard.h>
47 #include "../SDL_audiomem.h"
48 #include "../SDL_audio_c.h"
49 #include "../SDL_audiodev_c.h"
61 DSP_CloseDevice(
_THIS)
63 if (this->hidden !=
NULL) {
65 this->hidden->mixbuf =
NULL;
66 if (this->hidden->audio_fd >= 0) {
67 close(this->hidden->audio_fd);
68 this->hidden->audio_fd = -1;
77 DSP_OpenDevice(
_THIS,
const char *devname,
int iscapture)
87 if (devname ==
NULL) {
89 if (devname ==
NULL) {
96 if (this->spec.channels > 8)
97 this->spec.channels = 8;
98 else if (this->spec.channels > 4)
99 this->spec.channels = 4;
100 else if (this->spec.channels > 2)
101 this->spec.channels = 2;
106 if (this->hidden ==
NULL) {
109 SDL_memset(this->hidden, 0, (
sizeof *this->hidden));
112 this->hidden->audio_fd = open(devname, flags, 0);
113 if (this->hidden->audio_fd < 0) {
114 DSP_CloseDevice(
this);
115 return SDL_SetError(
"Couldn't open %s: %s", devname, strerror(errno));
117 this->hidden->mixbuf =
NULL;
122 ctlflags = fcntl(this->hidden->audio_fd, F_GETFL);
123 ctlflags &= ~O_NONBLOCK;
124 if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) {
125 DSP_CloseDevice(
this);
126 return SDL_SetError(
"Couldn't set audio blocking mode");
131 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
132 perror(
"SNDCTL_DSP_GETFMTS");
133 DSP_CloseDevice(
this);
140 !format && test_format;) {
142 fprintf(stderr,
"Trying format 0x%4.4x\n", test_format);
144 switch (test_format) {
146 if (value & AFMT_U8) {
151 if (value & AFMT_S16_LE) {
152 format = AFMT_S16_LE;
156 if (value & AFMT_S16_BE) {
157 format = AFMT_S16_BE;
166 if (value & AFMT_S8) {
171 if (value & AFMT_U16_LE) {
172 format = AFMT_U16_LE;
176 if (value & AFMT_U16_BE) {
177 format = AFMT_U16_BE;
190 DSP_CloseDevice(
this);
191 return SDL_SetError(
"Couldn't find any hardware audio formats");
193 this->spec.format = test_format;
197 if ((ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
199 perror(
"SNDCTL_DSP_SETFMT");
200 DSP_CloseDevice(
this);
205 value = this->spec.channels;
206 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
207 perror(
"SNDCTL_DSP_CHANNELS");
208 DSP_CloseDevice(
this);
209 return SDL_SetError(
"Cannot set the number of channels");
211 this->spec.channels =
value;
214 value = this->spec.freq;
215 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
216 perror(
"SNDCTL_DSP_SPEED");
217 DSP_CloseDevice(
this);
220 this->spec.freq =
value;
226 for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec);
227 if ((0x01U << frag_spec) != this->spec.size) {
228 DSP_CloseDevice(
this);
229 return SDL_SetError(
"Fragment size must be a power of two");
231 frag_spec |= 0x00020000;
235 fprintf(stderr,
"Requesting %d fragments of size %d\n",
236 (frag_spec >> 16), 1 << (frag_spec & 0xFFFF));
238 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
239 perror(
"SNDCTL_DSP_SETFRAGMENT");
244 ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info);
245 fprintf(stderr,
"fragments = %d\n", info.fragments);
246 fprintf(stderr,
"fragstotal = %d\n", info.fragstotal);
247 fprintf(stderr,
"fragsize = %d\n", info.fragsize);
248 fprintf(stderr,
"bytes = %d\n", info.bytes);
253 this->hidden->mixlen = this->spec.size;
255 if (this->hidden->mixbuf ==
NULL) {
256 DSP_CloseDevice(
this);
259 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
267 DSP_PlayDevice(
_THIS)
270 const int mixlen = this->hidden->mixlen;
271 if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) {
272 perror(
"Audio write");
276 fprintf(stderr,
"Wrote %d bytes of audio data\n", mixlen);
281 DSP_GetDeviceBuf(
_THIS)
283 return (this->hidden->mixbuf);
301 "dsp",
"OSS /dev/dsp standard audio", DSP_Init, 0
void(* CloseDevice)(_THIS)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
void(* SDL_AddAudioDevice)(const char *name)
void SDL_EnumUnixAudioDevices(int iscapture, int classic, int(*test)(int fd), SDL_AddAudioDevice addfn)
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)
SDL_AudioFormat SDL_NextAudioFormat(void)
void(* PlayDevice)(_THIS)
void(* DetectDevices)(int iscapture, SDL_AddAudioDevice addfn)
DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, int iscapture)
#define OPEN_FLAGS_OUTPUT
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
#define SDL_OutOfMemory()
AudioBootStrap DSP_bootstrap
EGLSurface EGLint void ** value
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
uint8_t Uint8
An unsigned 8-bit integer type.