Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve OSS backend support for JACK on non-Linux systems. #98

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 93 additions & 95 deletions drivers/oss/oss_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <config.h>

#define __BSD_VISIBLE 1
#ifdef USE_BARRIER
/*
* POSIX conformance level should be globally defined somewhere, possibly
Expand Down Expand Up @@ -57,6 +58,42 @@
#include <sys/ioctl.h>
#include <sys/soundcard.h>

#ifdef __linux__
#define AFMT_S32_LE 0x00001000
#define AFMT_S32_BE 0x00002000
#define AFMT_S24_LE 0x00008000
#define AFMT_S24_BE 0x00010000
#define AFMT_S24_PACKED 0x00040000

#ifndef OSS_ENDIAN
#ifdef __GNUC__
#if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__) || (defined(__sh__) && !defined(__LITTLE_ENDIAN__)))
#define OSS_LITTLE_ENDIAN 1234
#define OSS_ENDIAN OSS_LITTLE_ENDIAN
#else
#define OSS_BIG_ENDIAN 4321
#define OSS_ENDIAN OSS_BIG_ENDIAN
#endif
#else /* __GNUC__ */
#if (defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__))
#define OSS_BIG_ENDIAN 4321
#define OSS_ENDIAN OSS_BIG_ENDIAN
#else
#define OSS_LITTLE_ENDIAN 1234
#define OSS_ENDIAN OSS_LITTLE_ENDIAN
#endif
#endif /* __GNUC__ */
#endif /* OSS_ENDIAN */

#if (OSS_ENDIAN == 1234)
#define AFMT_S16_NE AFMT_S16_LE
#define AFMT_S32_NE AFMT_S32_LE
#else
#define AFMT_S16_NE AFMT_S16_BE
#define AFMT_S32_NE AFMT_S32_BE
#endif
#endif

#include <jack/types.h>
#include <jack/thread.h>

Expand Down Expand Up @@ -172,15 +209,19 @@ static void set_period_size (oss_driver_t *driver,
((double)driver->period_size /
(double)driver->sample_rate) * 1e6;
driver->last_wait_ust = 0;
driver->last_periodtime = driver->engine->get_microseconds ();
driver->last_periodtime = driver->engine ?
driver->engine->get_microseconds() :
jack_get_microseconds();
driver->next_periodtime = 0;
driver->iodelay = 0.0F;
}


static inline void update_times (oss_driver_t *driver)
{
driver->last_periodtime = driver->engine->get_microseconds ();
driver->last_periodtime = driver->engine ?
driver->engine->get_microseconds() :
jack_get_microseconds();
if (driver->next_periodtime > 0) {
driver->iodelay = (float)
((long double)driver->last_periodtime -
Expand Down Expand Up @@ -211,7 +252,7 @@ static void copy_and_convert_in (jack_sample_t *dst, void *src,
int dstidx;
signed short *s16src = (signed short*)src;
signed int *s32src = (signed int*)src;
double *f64src = (double*)src;
unsigned char *s24src = (unsigned char *)src;
jack_sample_t scale;

srcidx = channel;
Expand All @@ -225,10 +266,13 @@ static void copy_and_convert_in (jack_sample_t *dst, void *src,
}
break;
case 24:
scale = 1.0f / 0x7fffff;
scale = 1.0f / 0x7fffffff;
for (dstidx = 0; dstidx < nframes; dstidx++) {
dst[dstidx] = (jack_sample_t)
s32src[srcidx] * scale;
((signed int)(
(s24src[3 * srcidx + 2] << 24) |
(s24src[3 * srcidx + 1] << 16) |
(s24src[3 * srcidx + 0] << 8))) * scale;
srcidx += chcount;
}
break;
Expand All @@ -240,12 +284,6 @@ static void copy_and_convert_in (jack_sample_t *dst, void *src,
srcidx += chcount;
}
break;
case 64:
for (dstidx = 0; dstidx < nframes; dstidx++) {
dst[dstidx] = (jack_sample_t)f64src[srcidx];
srcidx += chcount;
}
break;
}
}

Expand All @@ -256,8 +294,8 @@ static void copy_and_convert_out (void *dst, jack_sample_t *src,
int srcidx;
int dstidx;
signed short *s16dst = (signed short*)dst;
unsigned char *s24dst = (unsigned char *)dst;
signed int *s32dst = (signed int*)dst;
double *f64dst = (double*)dst;
jack_sample_t scale;

dstidx = channel;
Expand All @@ -273,12 +311,15 @@ static void copy_and_convert_out (void *dst, jack_sample_t *src,
}
break;
case 24:
scale = 0x7fffff;
scale = 0x7fffffff;
for (srcidx = 0; srcidx < nframes; srcidx++) {
s32dst[dstidx] = (signed int)
(src[srcidx] >= 0.0f) ?
(src[srcidx] * scale + 0.5f) :
(src[srcidx] * scale - 0.5f);
signed int sample =
(src[srcidx] >= 0.0f) ?
(src[srcidx] * scale + 0.5f) :
(src[srcidx] * scale - 0.5f) ;
s24dst[3*dstidx + 2] = sample >> 24;
s24dst[3*dstidx + 1] = sample >> 16;
s24dst[3*dstidx + 0] = sample >> 8;
dstidx += chcount;
}
break;
Expand All @@ -292,12 +333,6 @@ static void copy_and_convert_out (void *dst, jack_sample_t *src,
dstidx += chcount;
}
break;
case 64:
for (srcidx = 0; srcidx < nframes; srcidx++) {
f64dst[dstidx] = (double)src[srcidx];
dstidx += chcount;
}
break;
}
}

Expand Down Expand Up @@ -429,7 +464,11 @@ static int oss_driver_detach (oss_driver_t *driver, jack_engine_t *engine)

static int oss_driver_start (oss_driver_t *driver)
{
int flags = 0;
#if defined(OPTION_COOKEDMODE)
int cookedmode = 1;
#else
int cookedmode = 0;
#endif
int format;
int channels;
int samplerate;
Expand All @@ -441,19 +480,7 @@ static int oss_driver_start (oss_driver_t *driver)
const char *indev = driver->indev;
const char *outdev = driver->outdev;

switch (driver->bits) {
case 24:
case 32:
samplesize = sizeof(int);
break;
case 64:
samplesize = sizeof(double);
break;
case 16:
default:
samplesize = sizeof(short);
break;
}
samplesize = driver->bits / 8;
driver->trigger = 0;
if (strcmp (indev, outdev) != 0) {
if (driver->capture_channels > 0) {
Expand All @@ -464,7 +491,7 @@ static int oss_driver_start (oss_driver_t *driver)
indev, __FILE__, __LINE__, errno);
}
#ifndef OSS_NO_COOKED_MODE
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &flags);
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &cookedmode);
#endif
fragsize = driver->period_size *
driver->capture_channels * samplesize;
Expand All @@ -479,7 +506,7 @@ static int oss_driver_start (oss_driver_t *driver)
outdev, __FILE__, __LINE__, errno);
}
#ifndef OSS_NO_COOKED_MODE
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &flags);
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &cookedmode);
#endif
fragsize = driver->period_size *
driver->playback_channels * samplesize;
Expand All @@ -497,7 +524,7 @@ static int oss_driver_start (oss_driver_t *driver)
return -1;
}
#ifndef OSS_NO_COOKED_MODE
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &flags);
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &cookedmode);
#endif
} else if (driver->capture_channels == 0 &&
driver->playback_channels != 0) {
Expand All @@ -510,7 +537,7 @@ static int oss_driver_start (oss_driver_t *driver)
return -1;
}
#ifndef OSS_NO_COOKED_MODE
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &flags);
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &cookedmode);
#endif
} else {
infd = outfd = open (indev, O_RDWR | O_EXCL);
Expand All @@ -521,7 +548,7 @@ static int oss_driver_start (oss_driver_t *driver)
return -1;
}
#ifndef OSS_NO_COOKED_MODE
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &flags);
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &cookedmode);
#endif
}
if (infd >= 0 && outfd >= 0) {
Expand Down Expand Up @@ -705,7 +732,9 @@ static int oss_driver_start (oss_driver_t *driver)
sem_post (&driver->sem_start);
}

driver->last_periodtime = driver->engine->get_microseconds ();
driver->last_periodtime = driver->engine ?
driver->engine->get_microseconds() :
jack_get_microseconds();
driver->next_periodtime = 0;
driver->iodelay = 0.0F;

Expand Down Expand Up @@ -1143,6 +1172,27 @@ jack_driver_t * driver_initialize (jack_client_t *client,
pnode = jack_slist_next (pnode);
}

switch (bits)
{
case 16: /* native-endian 16-bit integer */
driver->format = AFMT_S16_NE;
break;
case 24: /* little-endian 24-bit integer */
#ifdef __linux__
driver->format = AFMT_S24_PACKED;
#else
driver->format = AFMT_S24_LE;
#endif
break;
case 32: /* native-endian 32-bit integer */
driver->format = AFMT_S32_NE;
break;
default:
free(driver);
jack_error("OSS: invalid number of bits: %d",
__FILE__, __LINE__, bits);
return NULL;
}
driver->sample_rate = sample_rate;
driver->period_size = period_size;
driver->nperiods = nperiods;
Expand All @@ -1163,58 +1213,6 @@ jack_driver_t * driver_initialize (jack_client_t *client,
}
driver->infd = -1;
driver->outfd = -1;
switch (driver->bits) {
# ifndef OSS_ENDIAN
# ifdef __GNUC__
# if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__) || (defined(__sh__) && !defined(__LITTLE_ENDIAN__)))
# define OSS_LITTLE_ENDIAN 1234
# define OSS_ENDIAN OSS_LITTLE_ENDIAN
# else
# define OSS_BIG_ENDIAN 4321
# define OSS_ENDIAN OSS_BIG_ENDIAN
# endif
# else /* __GNUC__ */
# if (defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__))
# define OSS_BIG_ENDIAN 4321
# define OSS_ENDIAN OSS_BIG_ENDIAN
# else
# define OSS_LITTLE_ENDIAN 1234
# define OSS_ENDIAN OSS_LITTLE_ENDIAN
# endif
# endif /* __GNUC__ */
# endif /* OSS_ENDIAN */
# if (OSS_ENDIAN == 1234)
/* little-endian architectures */
case 24: /* little-endian LSB aligned 24-bits in 32-bits integer */
driver->format = 0x00008000;
break;
case 32: /* little-endian 32-bit integer */
driver->format = 0x00001000;
break;
case 64: /* native-endian 64-bit float */
driver->format = 0x00004000;
break;
case 16: /* little-endian 16-bit integer */
default:
driver->format = 0x00000010;
break;
/* big-endian architectures */
# else
case 24: /* big-endian LSB aligned 24-bits in 32-bits integer */
break;
driver->format = 0x00010000;
case 32: /* big-endian 32-bit integer */
driver->format = 0x00002000;
break;
case 64: /* native-endian 64-bit float */
driver->format = 0x00004000;
break;
case 16: /* big-endian 16-bit integer */
default:
driver->format = 0x00000020;
# endif
}

driver->indevbuf = driver->outdevbuf = NULL;

driver->capture_ports = NULL;
Expand Down