Skip to content

Commit

Permalink
-Add: add Open Sound System (OSS) support
Browse files Browse the repository at this point in the history
OSS is the prefered sound API under FreeBSD
ALSA is prefered under Linux
  • Loading branch information
miniupnp committed Feb 12, 2017
1 parent 131598b commit 2279813
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 1 deletion.
11 changes: 11 additions & 0 deletions config.lib
Expand Up @@ -42,6 +42,7 @@ set_default() {
with_sdlimage="1" with_sdlimage="1"
with_sdl2="1" with_sdl2="1"
with_asound="1" with_asound="1"
with_oss="1"
with_pulse="1" with_pulse="1"
with_munt="1" with_munt="1"
enable_builtin_depend="1" enable_builtin_depend="1"
Expand Down Expand Up @@ -79,6 +80,7 @@ set_default() {
with_sdlimage with_sdlimage
with_sdl2 with_sdl2
with_asound with_asound
with_oss
with_pulse with_pulse
with_munt with_munt
enable_builtin_depend enable_builtin_depend
Expand Down Expand Up @@ -188,6 +190,9 @@ detect_params() {
--without-alsa) with_asound="0";; --without-alsa) with_asound="0";;
--with-alsa=*) with_asound="$optarg";; --with-alsa=*) with_asound="$optarg";;


--with-oss) with_oss="2";;
--without-oss) with_oss="0";;

--with-pulse) with_pulse="2";; --with-pulse) with_pulse="2";;
--without-pulse) with_pulse="0";; --without-pulse) with_pulse="0";;
--with-pulse=*) with_pulse="$optarg";; --with-pulse=*) with_pulse="$optarg";;
Expand Down Expand Up @@ -439,9 +444,14 @@ check_params() {
with_sdl2="0" with_sdl2="0"
with_sdl="0" with_sdl="0"
with_asound="0" with_asound="0"
with_oss="0"
with_pulse="0" with_pulse="0"
with_munt="0" with_munt="0"
fi fi
if [ "$os" = "FREEBSD" ] && [ "$with_oss" != "0" ] && [ "$with_asound" = "1" ] ; then
# prefers OSS to ALSA under FreeBSD
with_asound="0"
fi
detect_sdl2 detect_sdl2
detect_sdl detect_sdl
detect_asound detect_asound
Expand Down Expand Up @@ -2037,6 +2047,7 @@ showhelp() {
echo " --with-sdl[=sdl-config] enables SDL video driver support" echo " --with-sdl[=sdl-config] enables SDL video driver support"
echo " --with-sdl2[=sdl2-config] enables SDL2 video driver support" echo " --with-sdl2[=sdl2-config] enables SDL2 video driver support"
echo " --with-asound[=libasound.a] enables ALSA support" echo " --with-asound[=libasound.a] enables ALSA support"
echo " --with-oss enables Open Sound System"
echo " --with-munt enables MUNT support" echo " --with-munt enables MUNT support"
echo " --with-pulse[=libpulse.a] enables PulseAudio support" echo " --with-pulse[=libpulse.a] enables PulseAudio support"
echo " --disable-builtin-depend disable use of builtin deps finder" echo " --disable-builtin-depend disable use of builtin deps finder"
Expand Down
3 changes: 2 additions & 1 deletion configure
Expand Up @@ -95,7 +95,8 @@ AWKCOMMAND='
if ($0 == "SDL2" && "'$sdl2_config'" == "") { next; } if ($0 == "SDL2" && "'$sdl2_config'" == "") { next; }
if ($0 == "SDL" && "'$sdl_config'" == "") { next; } if ($0 == "SDL" && "'$sdl_config'" == "") { next; }
if ($0 == "ALSA" && "'$with_asound'" == "0") { next; } if ($0 == "ALSA" && "'$with_asound'" == "0") { next; }
if ($0 == "MUNT" && "'$with_munt'" == "0") { next; } if ($0 == "OSS" && "'$with_oss'" == "0") { next; }
if ($0 == "MUNT" && "'$with_munt'" == "0") { next; }
if ($0 == "PULSE" && "'$with_pulse'" == "0") { next; } if ($0 == "PULSE" && "'$with_pulse'" == "0") { next; }
if ($0 == "OSX" && "'$os'" != "OSX") { next; } if ($0 == "OSX" && "'$os'" != "OSX") { next; }
if ($0 == "TOS" && "'$os'" != "TOS") { next; } if ($0 == "TOS" && "'$os'" != "TOS") { next; }
Expand Down
4 changes: 4 additions & 0 deletions source.list
Expand Up @@ -16,6 +16,9 @@ audio/midi_atari.c
#else #else
#if ALSA #if ALSA
audio/dsp_alsa.c audio/dsp_alsa.c
#else
#if OSS
audio/dsp_oss.c
#else #else
#if SDL #if SDL
audio/dsp_sdl.c audio/dsp_sdl.c
Expand All @@ -27,6 +30,7 @@ audio/midi_atari.c
#endif #endif
#endif #endif
#endif #endif
#endif
#endif #endif
# MIDI # MIDI
#if MUNT #if MUNT
Expand Down
160 changes: 160 additions & 0 deletions src/audio/dsp_oss.c
@@ -0,0 +1,160 @@
/** @file src/audio/dsp_oss.c OSS (Open Sound System) implementation of the DSP. */
/* OSS is deprecated under linux, but still used in *BSD world */

#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/soundcard.h>
#include "types.h"
#include "../timer.h"
#include "../os/error.h"
#include "../os/endian.h"

#include "dsp.h"

#define AUDIO_DEVICE "/dev/dsp"

static void oss_tick(void);

static int s_oss_fd = -1;

static const uint8 * s_data_to_play = NULL;
static size_t s_bytes_to_play = 0;

void DSP_Stop(void)
{
if(s_oss_fd >= 0) {
close(s_oss_fd);
s_oss_fd = -1;
}
}

void DSP_Uninit(void)
{
DSP_Stop();
Timer_Remove(oss_tick);
}

bool DSP_Init(void)
{
s_oss_fd = open(AUDIO_DEVICE, O_WRONLY);
if(s_oss_fd < 0) {
Error("DSP_Init() OSS : open(%s) : %s\n", AUDIO_DEVICE, strerror(errno));
return false;
}
#ifdef SNDCTL_SYSINFO
{
struct oss_sysinfo info;
if(ioctl(s_oss_fd, SNDCTL_SYSINFO, &info) < 0) {
Warning("ioctl(SNDCTL_SYSINFO) Failed : %s\n", strerror(errno));
} else {
Debug("DSP_Init() : %s version %s %d dsp devices\n",
info.product, info.version, info.numaudios);
}
}
#endif
close(s_oss_fd);
s_oss_fd = -1;
Timer_Add(oss_tick, 1000000 / 10, true);
return true;
}

void DSP_Play(const uint8 *data)
{
int i;
uint32 len;
int freq;
ssize_t n;

DSP_Stop();

data += READ_LE_UINT16(data + 20); /* skip Create Voice File header */

/* first byte is Block Type :
* 0x00: Terminator
* 0x01: Sound data
* 0x02: Sound data continuation
* 0x03: Silence
* 0x04: Marker
* 0x05: Text
* 0x06: Repeat start
* 0x07: Repeat end
* 0x08: Extra info
* 0x09: Sound data (New format) */
if (*data != 1) return;

/* next 3 bytes are block size (not including the 1 block type and size 4 bytes) */
len = (READ_LE_UINT32(data) >> 8) - 2;
data += 4;
/* byte 0 frequency divisor
* byte 1 codec id : 0 is "8bits unsigned PCM"
* bytes 2..n audio data */

freq = 1000000 / (256 - data[0]);
if (data[1] != 0) Warning("Unsupported VOC codec 0x%02x\n", (int)data[1]);

s_oss_fd = open(AUDIO_DEVICE, O_WRONLY);
if(s_oss_fd < 0) {
Error("open(%s) : %s\n", AUDIO_DEVICE, strerror(errno));
return;
}
i = AFMT_U8; /* Unsigned 8bit samples */
if(ioctl(s_oss_fd, SNDCTL_DSP_SETFMT, &i) < 0) {
Error("Failed to set unsigned 8bit format\n");
}
i = 0; /* MONO */
if(ioctl(s_oss_fd, SNDCTL_DSP_STEREO, &i) < 0) {
Error("Failed to set mono\n");
}
/*Debug("Setting sample rate = %d\n", freq);*/
if(ioctl(s_oss_fd, SNDCTL_DSP_SPEED, &freq) < 0) {
Error("Failed to set sample rate\n");
}
/*Debug("Real sample rate = %d\n", freq);*/

n = write(s_oss_fd, data + 2, len);
Debug("write() returned %d (len=%d)\n", (int)n, (int)len);
if(n < 0) {
if(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR) {
s_data_to_play = data + 2;
s_bytes_to_play = len;
} else {
Error("DSP_Play() write() : %s\n", strerror(errno));
}
} else if((int)n < (int)len) {
s_data_to_play = data + 2 + n;
s_bytes_to_play = len - n;
}
}

#define DELAY_THRESHOLD (16)

uint8 DSP_GetStatus(void)
{
int delay;
if(s_oss_fd < 0) return 0;
if(s_bytes_to_play > 0) return 2;
if(ioctl(s_oss_fd, SNDCTL_DSP_GETODELAY, &delay) < 0) {
Warning("ioctl SNDCTL_DSP_GETODELAY : %s\n", strerror(errno));
return 0;
}
if(delay < DELAY_THRESHOLD) return 0;
/*Debug("DSP_GetStatus() : delay=%d\n", delay);*/
return 2; /* playing */
}

static void oss_tick(void)
{
ssize_t n;
if(s_oss_fd >= 0 && s_bytes_to_play > 0) {
n = write(s_oss_fd, s_data_to_play, s_bytes_to_play);
/*Debug(" write() returned %d (len=%d)\n", (int)n, (int)s_bytes_to_play);*/
if(n < 0) {
Error("oss_tick() write() : %s\n", strerror(errno));
} else {
s_data_to_play += n;
s_bytes_to_play -= n;
}
}
}

0 comments on commit 2279813

Please sign in to comment.