ref: d75d78ae28fee905f82fb5d8b01aa57aaf0965d1
parent: 2ac72452933289412d3998810ba64627d4d2b5a4
author: cbagwell <cbagwell>
date: Thu Jan 25 17:45:10 EST 2001
Updating OSS driver to attempt to use multiple endian types if one fails. Found some endian code that wasn't updated in a few handlers.
--- a/Changelog
+++ b/Changelog
@@ -27,6 +27,9 @@
dropped under heavy CPU loads. Moved GETBLKSIZE operation
until after setting up the format (SBLive! was modify the block size
after changing formats).
+ o With help from David Blythe, updated OSS drivers to use newer format
+ interface. OSS driver will now attempt to detect a valid endian type
+ to use with sound card.
sox-12.17.1
-----------
--- a/src/oss.c
+++ b/src/oss.c
@@ -5,9 +5,8 @@
* any purpose. This copyright notice must be maintained.
* Chris Bagwell And Sundry Contributors are not
* responsible for the consequences of using this software.
- */
-
-/* Direct to Open Sound System (OSS) sound driver
+ *
+ * Direct to Open Sound System (OSS) sound driver
* OSS is a popular unix sound driver for Intel x86 unices (eg. Linux)
* and several other unixes (such as SunOS/Solaris).
* This driver is compatible with OSS original source that was called
@@ -44,12 +43,13 @@
static int ossdspinit(ft)
ft_t ft;
{
- int samplesize = 8, dsp_stereo;
- int tmp;
+ int sampletype, samplesize, dsp_stereo;
+ int tmp, rc;
if (ft->info.rate == 0.0) ft->info.rate = 8000;
if (ft->info.size == -1) ft->info.size = ST_SIZE_BYTE;
if (ft->info.size == ST_SIZE_BYTE) {
+ sampletype = AFMT_U8;
samplesize = 8;
if (ft->info.encoding == -1)
ft->info.encoding = ST_ENCODING_UNSIGNED;
@@ -60,6 +60,10 @@
}
}
else if (ft->info.size == ST_SIZE_WORD) {
+ if (ST_IS_BIGENDIAN)
+ sampletype = AFMT_S16_BE;
+ else
+ sampletype = AFMT_S16_LE;
samplesize = 16;
if (ft->info.encoding == -1)
ft->info.encoding = ST_ENCODING_SIGN2;
@@ -90,6 +94,79 @@
return (ST_EOF);
}
+#ifdef SNDCTL_DSP_SETFMT
+ tmp = sampletype;
+ rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
+
+ /* If we are unable to set format type, then we should try a few
+ * other format that we can handle.
+ */
+ if (rc < 0)
+ {
+ /* If using 16-bits, the sound card may just prefer to use
+ * an endian format different then the machine type.
+ * Try swaping data endian.
+ */
+ if (sampletype == AFMT_S16_LE || sampletype == AFMT_S16_BE)
+ {
+ if (sampletype == AFMT_S16_LE)
+ sampletype = AFMT_S16_BE;
+ else
+ sampletype = AFMT_S16_LE;
+
+ rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
+ if (rc < 0)
+ {
+ /* Must not like 16-bits, try 8-bits */
+ ft->info.size = ST_SIZE_WORD;
+ ft->info.encoding = ST_ENCODING_SIGN2;
+ st_report("OSS driver doesn't like signed words");
+ st_report("Forcing to unsigned bytes");
+ sampletype = AFMT_U8;
+ rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
+ }
+ else
+ /* That was successful so store that we need to swap */
+ ft->swap = ft->swap ? 0 : 1;
+
+ }
+ else
+ {
+ ft->info.size = ST_SIZE_WORD;
+ ft->info.encoding = ST_ENCODING_SIGNED2;
+ st_report("OSS driver doesn't like unsigned bytes");
+ st_report("Forcing to signed words");
+ if (ST_IS_BIGENDIAN)
+ sampletype = AFMT_S16_BE;
+ else
+ sampletype = AFMT_S16_LE;
+
+ rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
+
+ /* If it doesn't like that, try swaping endians */
+ if (sampletype == AFMT_S16_LE || sampletype == AFMT_S16_BE)
+ {
+ if (sampletype == AFMT_S16_LE)
+ sampletype = AFMT_S16_BE;
+ else
+ sampletype = AFMT_S16_LE;
+
+ rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
+ if (rc >= 0)
+ /* That was successful so store that we need to swap */
+ ft->swap = ft->swap ? 0 : 1;
+ }
+
+ }
+ /* Give up and exit */
+ if (rc < 0)
+ {
+ st_fail("Unable to set the sample size to %d", samplesize);
+ return (ST_EOF);
+ }
+ }
+#else
+ /* Odd dumb interface */
tmp = samplesize;
if (ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp) < 0)
{
@@ -96,6 +173,7 @@
st_fail("Unable to set the sample size to %d", samplesize);
return (ST_EOF);
}
+#endif
if (tmp != samplesize)
{
--- a/src/sf.c
+++ b/src/sf.c
@@ -139,8 +139,6 @@
SFHEADER sfhead;
SFCODE *sfcodep;
char *sfcharp;
- int littlendian = 1;
- char *endptr;
int rc;
/* Needed for rawwrite() */
@@ -151,14 +149,13 @@
sf->info.magic_union._magic_bytes.sf_magic1 = SF_MAGIC1;
sf->info.magic_union._magic_bytes.sf_magic2 = SF_MAGIC2;
sf->info.magic_union._magic_bytes.sf_param = 0;
- /* computer musicians can't code worth a damn */
- /* you don't see this kind of junk in any other format */
- endptr = (char *) &littlendian;
- *endptr = 1;
- if (littlendian == 1)
- sf->info.magic_union._magic_bytes.sf_machine = SF_VAX;
+
+ /* This file handler can handle both big and little endian data */
+ if (ST_IS_LITTLEENDIAN)
+ sf->info.magic_union._magic_bytes.sf_machine = SF_VAX;
else
- sf->info.magic_union._magic_bytes.sf_machine = SF_SUN;
+ sf->info.magic_union._magic_bytes.sf_machine = SF_SUN;
+
sf->info.sf_srate = ft->info.rate;
if (ft->info.size == ST_SIZE_FLOAT) {
sf->info.sf_packmode = SF_FLOAT;
--- a/src/smp.c
+++ b/src/smp.c
@@ -183,8 +183,6 @@
ft_t ft;
{
smp_t smp = (smp_t) ft->priv;
- int littlendian = 1;
- char *endptr;
int i;
int namelen, commentlen;
LONG samplestart;
@@ -191,10 +189,9 @@
struct smpheader header;
struct smptrailer trailer;
- endptr = (char *) &littlendian;
/* SMP is in Little Endian format. Swap whats read in on */
/* Big Endian machines. */
- if (!*endptr)
+ if (ST_IS_LITTLEENDIAN)
{
ft->swap = ft->swap ? 0 : 1;
}
@@ -341,16 +338,12 @@
int st_smpstartwrite(ft)
ft_t ft;
{
- int littlendian = 1;
- char *endptr;
-
smp_t smp = (smp_t) ft->priv;
struct smpheader header;
- endptr = (char *) &littlendian;
/* SMP is in Little Endian format. Swap whats read in on */
/* Big Endian machines. */
- if (!*endptr)
+ if (ST_IS_LITTLEENDIAN)
{
ft->swap = ft->swap ? 0 : 1;
}
--- a/src/sndrtool.c
+++ b/src/sndrtool.c
@@ -142,8 +142,6 @@
int st_sndrstartwrite(ft)
ft_t ft;
{
- int littlendian = 1;
- char *endptr;
int rc;
/* Needed for rawread() */
@@ -151,11 +149,10 @@
if (rc)
return rc;
- endptr = (char *) &littlendian;
/* sndr is in little endian format so
* swap bytes on big endian machines
*/
- if (!*endptr)
+ if (ST_IS_BIGENDIAN)
{
ft->swap = ft->swap ? 0 : 1;
}