|
|
@@ -23,6 +23,7 @@ |
|
|
|
|
|
|
|
|
#include <config.h> |
|
|
#include <config.h> |
|
|
|
|
|
|
|
|
|
|
|
#define __BSD_VISIBLE 1 |
|
|
#ifdef USE_BARRIER |
|
|
#ifdef USE_BARRIER |
|
|
/* |
|
|
/* |
|
|
* POSIX conformance level should be globally defined somewhere, possibly |
|
|
* POSIX conformance level should be globally defined somewhere, possibly |
|
|
@@ -57,6 +58,42 @@ |
|
|
#include <sys/ioctl.h> |
|
|
#include <sys/ioctl.h> |
|
|
#include <sys/soundcard.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/types.h> |
|
|
#include <jack/thread.h> |
|
|
#include <jack/thread.h> |
|
|
|
|
|
|
|
|
@@ -172,7 +209,9 @@ static void set_period_size (oss_driver_t *driver, |
|
|
((double)driver->period_size / |
|
|
((double)driver->period_size / |
|
|
(double)driver->sample_rate) * 1e6; |
|
|
(double)driver->sample_rate) * 1e6; |
|
|
driver->last_wait_ust = 0; |
|
|
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->next_periodtime = 0; |
|
|
driver->iodelay = 0.0F; |
|
|
driver->iodelay = 0.0F; |
|
|
} |
|
|
} |
|
|
@@ -180,7 +219,9 @@ static void set_period_size (oss_driver_t *driver, |
|
|
|
|
|
|
|
|
static inline void update_times (oss_driver_t *driver) |
|
|
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) { |
|
|
if (driver->next_periodtime > 0) { |
|
|
driver->iodelay = (float) |
|
|
driver->iodelay = (float) |
|
|
((long double)driver->last_periodtime - |
|
|
((long double)driver->last_periodtime - |
|
|
@@ -211,7 +252,7 @@ static void copy_and_convert_in (jack_sample_t *dst, void *src, |
|
|
int dstidx; |
|
|
int dstidx; |
|
|
signed short *s16src = (signed short*)src; |
|
|
signed short *s16src = (signed short*)src; |
|
|
signed int *s32src = (signed int*)src; |
|
|
signed int *s32src = (signed int*)src; |
|
|
double *f64src = (double*)src; |
|
|
|
|
|
|
|
|
unsigned char *s24src = (unsigned char *)src; |
|
|
jack_sample_t scale; |
|
|
jack_sample_t scale; |
|
|
|
|
|
|
|
|
srcidx = channel; |
|
|
srcidx = channel; |
|
|
@@ -225,10 +266,13 @@ static void copy_and_convert_in (jack_sample_t *dst, void *src, |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case 24: |
|
|
case 24: |
|
|
scale = 1.0f / 0x7fffff; |
|
|
|
|
|
|
|
|
scale = 1.0f / 0x7fffffff; |
|
|
for (dstidx = 0; dstidx < nframes; dstidx++) { |
|
|
for (dstidx = 0; dstidx < nframes; dstidx++) { |
|
|
dst[dstidx] = (jack_sample_t) |
|
|
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; |
|
|
srcidx += chcount; |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
@@ -240,12 +284,6 @@ static void copy_and_convert_in (jack_sample_t *dst, void *src, |
|
|
srcidx += chcount; |
|
|
srcidx += chcount; |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case 64: |
|
|
|
|
|
for (dstidx = 0; dstidx < nframes; dstidx++) { |
|
|
|
|
|
dst[dstidx] = (jack_sample_t)f64src[srcidx]; |
|
|
|
|
|
srcidx += chcount; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -256,8 +294,8 @@ static void copy_and_convert_out (void *dst, jack_sample_t *src, |
|
|
int srcidx; |
|
|
int srcidx; |
|
|
int dstidx; |
|
|
int dstidx; |
|
|
signed short *s16dst = (signed short*)dst; |
|
|
signed short *s16dst = (signed short*)dst; |
|
|
|
|
|
unsigned char *s24dst = (unsigned char *)dst; |
|
|
signed int *s32dst = (signed int*)dst; |
|
|
signed int *s32dst = (signed int*)dst; |
|
|
double *f64dst = (double*)dst; |
|
|
|
|
|
jack_sample_t scale; |
|
|
jack_sample_t scale; |
|
|
|
|
|
|
|
|
dstidx = channel; |
|
|
dstidx = channel; |
|
|
@@ -273,12 +311,15 @@ static void copy_and_convert_out (void *dst, jack_sample_t *src, |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case 24: |
|
|
case 24: |
|
|
scale = 0x7fffff; |
|
|
|
|
|
|
|
|
scale = 0x7fffffff; |
|
|
for (srcidx = 0; srcidx < nframes; srcidx++) { |
|
|
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; |
|
|
dstidx += chcount; |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
@@ -292,12 +333,6 @@ static void copy_and_convert_out (void *dst, jack_sample_t *src, |
|
|
dstidx += chcount; |
|
|
dstidx += chcount; |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case 64: |
|
|
|
|
|
for (srcidx = 0; srcidx < nframes; srcidx++) { |
|
|
|
|
|
f64dst[dstidx] = (double)src[srcidx]; |
|
|
|
|
|
dstidx += chcount; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -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) |
|
|
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 format; |
|
|
int channels; |
|
|
int channels; |
|
|
int samplerate; |
|
|
int samplerate; |
|
|
@@ -441,19 +480,7 @@ static int oss_driver_start (oss_driver_t *driver) |
|
|
const char *indev = driver->indev; |
|
|
const char *indev = driver->indev; |
|
|
const char *outdev = driver->outdev; |
|
|
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; |
|
|
driver->trigger = 0; |
|
|
if (strcmp (indev, outdev) != 0) { |
|
|
if (strcmp (indev, outdev) != 0) { |
|
|
if (driver->capture_channels > 0) { |
|
|
if (driver->capture_channels > 0) { |
|
|
@@ -464,7 +491,7 @@ static int oss_driver_start (oss_driver_t *driver) |
|
|
indev, __FILE__, __LINE__, errno); |
|
|
indev, __FILE__, __LINE__, errno); |
|
|
} |
|
|
} |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &flags); |
|
|
|
|
|
|
|
|
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &cookedmode); |
|
|
#endif |
|
|
#endif |
|
|
fragsize = driver->period_size * |
|
|
fragsize = driver->period_size * |
|
|
driver->capture_channels * samplesize; |
|
|
driver->capture_channels * samplesize; |
|
|
@@ -479,7 +506,7 @@ static int oss_driver_start (oss_driver_t *driver) |
|
|
outdev, __FILE__, __LINE__, errno); |
|
|
outdev, __FILE__, __LINE__, errno); |
|
|
} |
|
|
} |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &flags); |
|
|
|
|
|
|
|
|
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &cookedmode); |
|
|
#endif |
|
|
#endif |
|
|
fragsize = driver->period_size * |
|
|
fragsize = driver->period_size * |
|
|
driver->playback_channels * samplesize; |
|
|
driver->playback_channels * samplesize; |
|
|
@@ -497,7 +524,7 @@ static int oss_driver_start (oss_driver_t *driver) |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &flags); |
|
|
|
|
|
|
|
|
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &cookedmode); |
|
|
#endif |
|
|
#endif |
|
|
} else if (driver->capture_channels == 0 && |
|
|
} else if (driver->capture_channels == 0 && |
|
|
driver->playback_channels != 0) { |
|
|
driver->playback_channels != 0) { |
|
|
@@ -510,7 +537,7 @@ static int oss_driver_start (oss_driver_t *driver) |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &flags); |
|
|
|
|
|
|
|
|
ioctl (outfd, SNDCTL_DSP_COOKEDMODE, &cookedmode); |
|
|
#endif |
|
|
#endif |
|
|
} else { |
|
|
} else { |
|
|
infd = outfd = open (indev, O_RDWR | O_EXCL); |
|
|
infd = outfd = open (indev, O_RDWR | O_EXCL); |
|
|
@@ -521,7 +548,7 @@ static int oss_driver_start (oss_driver_t *driver) |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
#ifndef OSS_NO_COOKED_MODE |
|
|
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &flags); |
|
|
|
|
|
|
|
|
ioctl (infd, SNDCTL_DSP_COOKEDMODE, &cookedmode); |
|
|
#endif |
|
|
#endif |
|
|
} |
|
|
} |
|
|
if (infd >= 0 && outfd >= 0) { |
|
|
if (infd >= 0 && outfd >= 0) { |
|
|
@@ -705,7 +732,9 @@ static int oss_driver_start (oss_driver_t *driver) |
|
|
sem_post (&driver->sem_start); |
|
|
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->next_periodtime = 0; |
|
|
driver->iodelay = 0.0F; |
|
|
driver->iodelay = 0.0F; |
|
|
|
|
|
|
|
|
@@ -1143,6 +1172,27 @@ jack_driver_t * driver_initialize (jack_client_t *client, |
|
|
pnode = jack_slist_next (pnode); |
|
|
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->sample_rate = sample_rate; |
|
|
driver->period_size = period_size; |
|
|
driver->period_size = period_size; |
|
|
driver->nperiods = nperiods; |
|
|
driver->nperiods = nperiods; |
|
|
@@ -1163,58 +1213,6 @@ jack_driver_t * driver_initialize (jack_client_t *client, |
|
|
} |
|
|
} |
|
|
driver->infd = -1; |
|
|
driver->infd = -1; |
|
|
driver->outfd = -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->indevbuf = driver->outdevbuf = NULL; |
|
|
|
|
|
|
|
|
driver->capture_ports = NULL; |
|
|
driver->capture_ports = NULL; |
|
|
|