23 #include <sys/ioctl.h>
37 #include <sys/soundcard.h>
43 #ifndef SOUND_MIXER_READ
44 #define SOUND_MIXER_READ MIXER_READ
46 #ifndef SOUND_MIXER_WRITE
47 #define SOUND_MIXER_WRITE MIXER_WRITE
91 while(!data->killNow && Device->
Connected)
94 ALubyte *WritePtr = data->mix_data;
97 while(len > 0 && !data->killNow)
99 wrote = write(data->fd, WritePtr, len);
102 if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
104 ERR(
"write failed: %s\n", strerror(errno));
134 while(!data->killNow)
136 amt = read(data->fd, data->mix_data, data->data_size);
139 ERR(
"read failed: %s\n", strerror(errno));
166 data = (oss_data*)
calloc(1,
sizeof(oss_data));
194 int numFragmentsLogSize;
195 int log2FragmentSize;
196 unsigned int periods;
219 ossFormat = AFMT_S16_NE;
231 if (log2FragmentSize < 4)
232 log2FragmentSize = 4;
235 if(periods > 2) periods--;
236 numFragmentsLogSize = (periods << 16) | log2FragmentSize;
238 #define CHECKERR(func) if((func) < 0) { \
244 ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
245 CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
246 CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
247 CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
248 CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info));
252 ERR(
"%s failed: %s\n", err, strerror(errno));
272 device->
UpdateSize = info.fragsize / frameSize;
285 data->mix_data =
calloc(1, data->data_size);
288 if(data->thread ==
NULL)
290 free(data->mix_data);
291 data->mix_data =
NULL;
310 if(ioctl(data->fd, SNDCTL_DSP_RESET) != 0)
311 ERR(
"Error resetting device: %s\n", strerror(errno));
313 free(data->mix_data);
314 data->mix_data =
NULL;
320 int numFragmentsLogSize;
321 int log2FragmentSize;
322 unsigned int periods;
336 data = (oss_data*)
calloc(1,
sizeof(oss_data));
356 ossFormat = AFMT_S16_NE;
372 frameSize / periods);
375 if (log2FragmentSize < 4)
376 log2FragmentSize = 4;
377 numFragmentsLogSize = (periods << 16) | log2FragmentSize;
379 #define CHECKERR(func) if((func) < 0) { \
383 CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize));
384 CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
385 CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
386 CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
387 CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETISPACE, &info));
391 ERR(
"%s failed: %s\n", err, strerror(errno));
419 ERR(
"Ring buffer create failed\n");
425 data->data_size = info.fragsize;
426 data->mix_data =
calloc(1, data->data_size);
430 if(data->thread ==
NULL)
433 free(data->mix_data);
452 free(data->mix_data);
static const BackendFuncs oss_funcs
int ConfigValueStr(const char *blockName, const char *keyName, const char **ret)
static ALCboolean oss_start_playback(ALCdevice *device)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
char * strdup(const char *inStr)
static ALuint OSSCaptureProc(ALvoid *ptr)
const ALCchar * DevFmtChannelsString(enum DevFmtChannels chans)
void alc_oss_probe(enum DevProbe type)
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
static ALuint OSSProc(ALvoid *ptr)
static int log2i(ALCuint x)
ALsizei RingBufferSize(RingBuffer *ring)
void SetDefaultChannelOrder(ALCdevice *device)
void AppendCaptureDeviceList(const ALCchar *name)
ALvoid aluHandleDisconnect(ALCdevice *device)
#define ALCdevice_Unlock(a)
struct RingBuffer RingBuffer
ALuint StopThread(ALvoid *thread)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
static void oss_stop_playback(ALCdevice *device)
RingBuffer * CreateRingBuffer(ALsizei frame_size, ALsizei length)
void alc_oss_deinit(void)
static const char * oss_driver
enum DevFmtChannels FmtChans
static void oss_close_playback(ALCdevice *device)
static SDL_Thread * thread
static const char * oss_capture
EGLSurface EGLint EGLint y
void ALCdevice_LockDefault(ALCdevice *device)
ALCboolean alc_oss_init(BackendFuncs *func_list)
static const ALCchar oss_device[]
static void oss_stop_capture(ALCdevice *Device)
#define ALC_INVALID_VALUE
#define ALC_OUT_OF_MEMORY
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
static ALCenum oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
static ALCboolean oss_reset_playback(ALCdevice *device)
const ALCchar * DevFmtTypeString(enum DevFmtType type)
ALuint BytesFromDevFmt(enum DevFmtType type)
static void oss_start_capture(ALCdevice *Device)
static void oss_close_capture(ALCdevice *device)
void DestroyRingBuffer(RingBuffer *ring)
void ALCdevice_UnlockDefault(ALCdevice *device)
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
static ALCenum oss_capture_samples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples)
#define ALCdevice_Lock(a)
static ALCuint oss_available_samples(ALCdevice *Device)
void AppendAllDevicesList(const ALCchar *name)
ALvoid * StartThread(ALuint(*func)(ALvoid *), ALvoid *ptr)
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)