aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2008-09-07 14:34:14 -0700
committerChris Robinson <[email protected]>2008-09-07 14:34:14 -0700
commit16d96eed7bc8b412f06dccfa9c01f1bb7856bb91 (patch)
tree35ce4268f45597750248fe5093022c42710e8a51
parentfa76168683863aeab8430110ffed58cf1041677e (diff)
Add a Solaris playback backend
-rw-r--r--Alc/ALc.c3
-rw-r--r--Alc/solaris.c258
-rw-r--r--CMakeLists.txt11
-rw-r--r--OpenAL32/Include/alMain.h1
-rw-r--r--alsoftrc.sample6
-rw-r--r--config.h.in3
6 files changed, 281 insertions, 1 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 971eb827..223a000e 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -58,6 +58,9 @@ static struct {
#ifdef HAVE_OSS
{ "oss", alc_oss_init, EmptyFuncs },
#endif
+#ifdef HAVE_SOLARIS
+ { "solaris", alc_solaris_init, EmptyFuncs },
+#endif
#ifdef HAVE_DSOUND
{ "dsound", alcDSoundInit, EmptyFuncs },
#endif
diff --git a/Alc/solaris.c b/Alc/solaris.c
new file mode 100644
index 00000000..66f41730
--- /dev/null
+++ b/Alc/solaris.c
@@ -0,0 +1,258 @@
+/**
+ * OpenAL cross platform audio library
+ * Copyright (C) 1999-2007 by authors.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * Or go to http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#include "config.h"
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+#include "alMain.h"
+#include "AL/al.h"
+#include "AL/alc.h"
+
+#include <sys/audioio.h>
+
+
+static char *solaris_device;
+
+typedef struct {
+ int fd;
+ volatile int killNow;
+ ALvoid *thread;
+
+ ALubyte *mix_data;
+ int data_size;
+} solaris_data;
+
+
+static ALuint SolarisProc(ALvoid *ptr)
+{
+ ALCdevice *pDevice = (ALCdevice*)ptr;
+ solaris_data *data = (solaris_data*)pDevice->ExtraData;
+ int remaining = 0;
+ int wrote;
+
+ while(!data->killNow)
+ {
+ int len = data->data_size - remaining;
+
+ if(len > 0)
+ {
+ SuspendContext(NULL);
+ aluMixData(pDevice->Context, data->mix_data+remaining, len, pDevice->Format);
+ ProcessContext(NULL);
+ }
+
+ remaining += len;
+ wrote = write(data->fd, data->mix_data, remaining);
+ if(wrote < 0)
+ {
+ AL_PRINT("write failed: %s\n", strerror(errno));
+ remaining = 0;
+ }
+ else if(wrote > 0)
+ {
+ remaining -= wrote;
+ if(remaining > 0)
+ memmove(data->mix_data, data->mix_data+wrote, remaining);
+ }
+ else
+ Sleep(1);
+ }
+
+ return 0;
+}
+
+
+static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *deviceName)
+{
+ audio_info_t info;
+ ALuint frameSize;
+ char driver[64];
+ int numChannels;
+ solaris_data *data;
+
+ strncpy(driver, GetConfigValue("solaris", "device", "/dev/audio"), sizeof(driver)-1);
+ driver[sizeof(driver)-1] = 0;
+ if(deviceName)
+ {
+ if(strcmp(deviceName, solaris_device))
+ return ALC_FALSE;
+ device->szDeviceName = solaris_device;
+ }
+ else
+ device->szDeviceName = solaris_device;
+
+ data = (solaris_data*)calloc(1, sizeof(solaris_data));
+ data->killNow = 0;
+
+ data->fd = open(driver, O_WRONLY);
+ if(data->fd == -1)
+ {
+ free(data);
+ AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
+ return ALC_FALSE;
+ }
+
+ numChannels = aluChannelsFromFormat(device->Format);
+ AUDIO_INITINFO(&info);
+ info.play.sample_rate = device->Frequency;
+ info.play.channels = numChannels;
+
+ switch(aluBytesFromFormat(device->Format))
+ {
+ case 1:
+ info.play.precision = 8;
+ info.play.encoding = AUDIO_ENCODING_LINEAR8;
+ break;
+ case 2:
+ info.play.precision = 16;
+ info.play.encoding = AUDIO_ENCODING_LINEAR;
+ break;
+ default:
+ AL_PRINT("Unknown format?! %x\n", device->Format);
+ }
+
+ frameSize = numChannels * aluBytesFromFormat(device->Format);
+ info.play.buffer_size = device->UpdateSize * frameSize;
+
+ if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0)
+ {
+ AL_PRINT("ioctl failed: %s\n", strerror(errno));
+ close(data->fd);
+ free(data);
+ return ALC_FALSE;
+ }
+
+ device->Frequency = info.play.sample_rate;
+
+ if(aluChannelsFromFormat(device->Format) != info.play.channels)
+ {
+ AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), info.play.channels);
+ close(data->fd);
+ free(data);
+ return ALC_FALSE;
+ }
+
+ if(!((info.play.precision == 8 && aluBytesFromFormat(device->Format) == 1) ||
+ (info.play.precision == 16 && aluBytesFromFormat(device->Format) == 2)))
+ {
+ AL_PRINT("Could not set %d-bit output, got %d\n", aluBytesFromFormat(device->Format)*8, info.play.precision);
+ close(data->fd);
+ free(data);
+ return ALC_FALSE;
+ }
+
+ device->UpdateSize = info.play.buffer_size / 4;
+
+ data->data_size = device->UpdateSize * frameSize;
+ data->mix_data = calloc(1, data->data_size);
+
+ device->ExtraData = data;
+ data->thread = StartThread(SolarisProc, device);
+ if(data->thread == NULL)
+ {
+ device->ExtraData = NULL;
+ free(data->mix_data);
+ free(data);
+ return ALC_FALSE;
+ }
+
+ return ALC_TRUE;
+}
+
+static void solaris_close_playback(ALCdevice *device)
+{
+ solaris_data *data = (solaris_data*)device->ExtraData;
+ data->killNow = 1;
+ StopThread(data->thread);
+
+ close(data->fd);
+
+ free(data->mix_data);
+ free(data);
+ device->ExtraData = NULL;
+}
+
+
+static ALCboolean solaris_open_capture(ALCdevice *device, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
+{
+ (void)device;
+ (void)deviceName;
+ (void)frequency;
+ (void)format;
+ (void)SampleSize;
+ return ALC_FALSE;
+}
+
+static void solaris_close_capture(ALCdevice *device)
+{
+ (void)device;
+}
+
+static void solaris_start_capture(ALCdevice *pDevice)
+{
+ (void)pDevice;
+}
+
+static void solaris_stop_capture(ALCdevice *pDevice)
+{
+ (void)pDevice;
+}
+
+static void solaris_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
+{
+ (void)pDevice;
+ (void)pBuffer;
+ (void)lSamples;
+}
+
+static ALCuint solaris_available_samples(ALCdevice *pDevice)
+{
+ (void)pDevice;
+ return 0;
+}
+
+
+BackendFuncs solaris_funcs = {
+ solaris_open_playback,
+ solaris_close_playback,
+ solaris_open_capture,
+ solaris_close_capture,
+ solaris_start_capture,
+ solaris_stop_capture,
+ solaris_capture_samples,
+ solaris_available_samples
+};
+
+void alc_solaris_init(BackendFuncs *func_list)
+{
+ *func_list = solaris_funcs;
+
+ solaris_device = AppendDeviceList("Solaris Software");
+ AppendAllDeviceList(solaris_device);
+}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8e22ad27..a2afea99 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,7 @@ SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE)
OPTION(ALSA "Check for ALSA backend" ON)
OPTION(OSS "Check for OSS backend" ON)
+OPTION(SOLARIS "Check for Solaris backend" ON)
OPTION(DSOUND "Check for DirectSound backend" ON)
OPTION(WINMM "Check for Windows Multimedia backend" ON)
@@ -264,6 +265,16 @@ IF(OSS)
ENDIF()
ENDIF()
+# Check Solaris backend
+IF(SOLARIS)
+ CHECK_INCLUDE_FILE(sys/audioio.h HAVE_SYS_AUDIOIO_H)
+ IF(HAVE_SYS_AUDIOIO_H)
+ SET(HAVE_SOLARIS 1)
+ SET(ALC_OBJS ${ALC_OBJS} Alc/solaris.c)
+ SET(BACKENDS "${BACKENDS} Solaris,")
+ ENDIF()
+ENDIF()
+
# Check DSound/MMSystem backend
IF(HAVE_WINDOWS_H)
IF(DSOUND)
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index aadb71ba..fb9cfb5e 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -144,6 +144,7 @@ typedef struct {
void alc_alsa_init(BackendFuncs *func_list);
void alc_oss_init(BackendFuncs *func_list);
+void alc_solaris_init(BackendFuncs *func_list);
void alcDSoundInit(BackendFuncs *func_list);
void alcWinMMInit(BackendFuncs *FuncList);
void alc_wave_init(BackendFuncs *func_list);
diff --git a/alsoftrc.sample b/alsoftrc.sample
index acc64b53..ab1faee0 100644
--- a/alsoftrc.sample
+++ b/alsoftrc.sample
@@ -57,7 +57,7 @@ drivers = # Sets the backend driver list order, comma-seperated. Unknown
# backends and duplicated names are ignored, and unlisted backends
# won't be considered for use. An empty list means the default.
# Default is:
- # alsa,oss,dsound,winmm,wave
+ # alsa,oss,solaris,dsound,winmm,wave
[alsa] # ALSA backend stuff
device = default # Sets the device name for the default playback device.
@@ -82,6 +82,10 @@ periods = 4 # Sets the number of update buffers. Default is 4
capture = /dev/dsp # Sets the device name for OSS capture. Default is /dev/dsp
+[solaris] # Solaris backend stuff
+device = /dev/audio # Sets the device name for Solaris output. Default is
+ # /dev/audio
+
[dsound] # DirectSound backend stuff
# Nothing yet...
diff --git a/config.h.in b/config.h.in
index 7b310f3b..733c348b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -7,6 +7,9 @@
/* Define if we have the OSS backend */
#cmakedefine HAVE_OSS
+/* Define if we have the Solaris backend */
+#cmakedefine HAVE_SOLARIS
+
/* Define if we have the DSound backend */
#cmakedefine HAVE_DSOUND