From: Eric L. <sox...@li...> - 2010-11-04 19:45:11
|
Hi, I recently tried playing 24-bit flac files on my RME9652 card. It turned out to be a hassle to get it working, since the RME9652 doesn't accept SND_PCM_ACCESS_RW_INTERLEAVED. I eventually got it working by messing with my .asoundrc, but I thought OSS ought to be working too. The OSS-over-ALSA emulation in Linux supports 24- and 32-bit output, but sox doesn't know about it. So I wrote the patch below. It's pretty straightforward. I left out 24-bit support, since that just produced noise, probably because sox packs the samples in 3 bytes (is that true? I didn't check) and OSS expects them in 4 bytes. Anyway, I don't think 24-bit support would add any value if we have 32-bit support. cheers, Eric Index: src/oss.c =================================================================== RCS file: /cvsroot/sox/sox/src/oss.c,v retrieving revision 1.67 diff -u -w -r1.67 oss.c --- src/oss.c 7 Feb 2009 07:49:16 -0000 1.67 +++ src/oss.c 4 Nov 2010 19:11:19 -0000 @@ -36,6 +36,17 @@ #include <machine/soundcard.h> #endif +/* these appear in the sys/soundcard.h of OSS 4.x, and in Linux's + * sound/core/oss/pcm_oss.c (2.6.24 and later), but are typically + * not included in system header files. + */ +#ifndef AFMT_S32_LE +#define AFMT_S32_LE 0x00001000 +#endif +#ifndef AFMT_S32_BE +#define AFMT_S32_BE 0x00002000 +#endif + #include <sys/ioctl.h> typedef sox_fileinfo_t priv_t; @@ -72,6 +83,21 @@ ft->encoding.encoding = SOX_ENCODING_SIGN2; } } + else if (ft->encoding.bits_per_sample == 32) { + /* Attempt to use endian that user specified */ + if (ft->encoding.reverse_bytes) + sampletype = (MACHINE_IS_BIGENDIAN) ? AFMT_S32_LE : AFMT_S32_BE; + else + sampletype = (MACHINE_IS_BIGENDIAN) ? AFMT_S32_BE : AFMT_S32_LE; + samplesize = 32; + if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN) + ft->encoding.encoding = SOX_ENCODING_SIGN2; + if (ft->encoding.encoding != SOX_ENCODING_SIGN2) { + lsx_report("OSS driver only supports signed with words"); + lsx_report("Forcing to signed linear"); + ft->encoding.encoding = SOX_ENCODING_SIGN2; + } + } else { /* Attempt to use endian that user specified */ if (ft->encoding.reverse_bytes) @@ -199,7 +225,7 @@ { static char const * const names[] = {"ossdsp", "oss", NULL}; static unsigned const write_encodings[] = { - SOX_ENCODING_SIGN2, 16, 0, + SOX_ENCODING_SIGN2, 32, 16, 0, SOX_ENCODING_UNSIGNED, 8, 0, 0}; static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE, |