On Tue, Feb 01, 2005 at 05:04:42PM +0100, Daniel Kobras wrote:
> Thanks. I had already looked through the bplay BTS entries, found the
> patches there and decided to craft my own. It's ready but stupid me
> forgot to apply the current patches to gramofile first, so I'll have to
> go through another round and do some patch merging. I'll attach the
> original version against the pristine upstream source for reference.
nice. attached is the patch corrected for fmtheaders (could benefit
fiddling a bit with the line numbers to avoid the warnings). your patch
seems to produce cleaner files than mine (aplay like them), altough i
still get Premature EOF with.
> > And at the end of the recording, when showing the 'Recording
> > information', brec_gramo eats all the cpu available until OK is pressed.
>
> WAV format as spec'ed is limited to a 2GB max. file size. Therefore,
> apart from the sanity checks I see little use in applying the LFS
> patches.
agreed. the cpu eating is quite a problem though, but this is another
story. i guess shmbuf.c would need a bit of cleanup too.
ciao, piem.
# Fix endianness bugs in WAV and VOC headers on big-endian archs.
# Use POSIX size types to avoid broken headers on 64bit archs.
# Disable padding in structs that read/write raw on-disk data.
# [dk]
#PATCHOPTIONS: -p0
Index: bplaysrc/bplay.c
===================================================================
RCS file: /home/kobras/cvsroot/debian/gramofile/bplaysrc/bplay.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 bplay.c
--- bplaysrc/bplay.c 2001/05/05 14:07:15 1.1.1.2
+++ bplaysrc/bplay.c 2005/01/31 15:54:06
@@ -26,6 +26,30 @@
#include <machine/soundcard.h>
#endif
+/* Needed for BYTE_ORDER and BIG/LITTLE_ENDIAN macros. */
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+# include <endian.h>
+# undef _BSD_SOURCE
+#else
+# include <endian.h>
+#endif
+
+#include <sys/types.h>
+#include <byteswap.h>
+
+/* Adapted from the byteorder macros in the Linux kernel. */
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define cpu_to_le32(x) (x)
+#define cpu_to_le16(x) (x)
+#else
+#define cpu_to_le32(x) bswap_32((x))
+#define cpu_to_le16(x) bswap_16((x))
+#endif
+
+#define le32_to_cpu(x) cpu_to_le32((x))
+#define le16_to_cpu(x) cpu_to_le16((x))
+
#include "fmtheaders.h"
#include "../yesnowindow.h"
@@ -290,23 +314,26 @@
char *data = "data";
memcpy(&(header.main_chunk), riff, 4);
- header.length = sizeof(wavhead) - 8 + bcount;
+ header.length = cpu_to_le32(sizeof(wavhead)
+ - 8 + bcount);
memcpy(&(header.chunk_type), wave, 4);
memcpy(&(header.sub_chunk), fmt, 4);
- header.sc_len = 16;
- header.format = 1;
- header.modus = stereo + 1;
- header.sample_fq = speed;
- header.byte_p_sec = ((bits > 8)?
2:1)*(stereo+1)*speed;
+ header.sc_len = cpu_to_le32(16);
+ header.format = cpu_to_le16(1);
+ header.modus = cpu_to_le16(stereo + 1);
+ header.sample_fq = cpu_to_le32(speed);
+ header.byte_p_sec = cpu_to_le32(((bits > 8)?
+ 2:1)*(stereo+1)*speed);
/* Correction by J.A. Bezemer: */
- header.byte_p_spl = ((bits > 8)?
2:1)*(stereo+1);
+ header.byte_p_spl = cpu_to_le16(((bits > 8)?
+ 2:1)*(stereo+1));
/* was: header.byte_p_spl = (bits > 8)? 2:1; */
- header.bit_p_spl = bits;
+ header.bit_p_spl = cpu_to_le16(bits);
memcpy(&(header.data_chunk), data, 4);
- header.data_length = bcount;
+ header.data_length = cpu_to_le32(bcount);
write(thefd, &header, sizeof(header));
}
case F_RAW:
@@ -336,9 +363,9 @@
for (i=0;i<20;i++)
header.Magic[i] = VOC_MAGIC[i];
- header.BlockOffset = 0x1a;
- header.Version = 0x0114;
- header.IDCode = 0x111F;
+ header.BlockOffset = cpu_to_le16(0x1a);
+ header.Version = cpu_to_le16(0x0114);
+ header.IDCode = cpu_to_le16(0x111F);
write(thefd, &header, sizeof(vochead));
snd_parm(speed, bits, stereo);
@@ -349,10 +376,10 @@
ablk.BlockLen[0] = (i + 12) & 0xFF;
ablk.BlockLen[1] = ((i + 12) >> 8) & 0xFF;
ablk.BlockLen[2] = ((i + 12) >> 16) & 0xFF;
- bblk.SamplesPerSec = speed;
+ bblk.SamplesPerSec = cpu_to_le32(speed);
bblk.BitsPerSample = bits;
bblk.Channels = stereo + 1;
- bblk.Format = (bits == 8)? 0 : 4;
+ bblk.Format = cpu_to_le16((bits == 8)? 0 : 4);
write(thefd, &ablk, sizeof(ablk));
write(thefd, &bblk, sizeof(bblk));
shmrec(thefd, i, 1);
@@ -476,6 +503,17 @@
memcpy((void*)&wavhd, (void*)hd_buf, 20);
count = read(thefd, ((char*)&wavhd)+20, sizeof(wavhd) - 20);
+
+ wavhd.length = le32_to_cpu(wavhd.length);
+ wavhd.sc_len = le32_to_cpu(wavhd.sc_len);
+ wavhd.format = le16_to_cpu(wavhd.format);
+ wavhd.modus = le16_to_cpu(wavhd.modus);
+ wavhd.sample_fq = le32_to_cpu(wavhd.sample_fq);
+ wavhd.byte_p_sec = le32_to_cpu(wavhd.byte_p_sec);
+ wavhd.byte_p_spl = le16_to_cpu(wavhd.byte_p_spl);
+ wavhd.bit_p_spl = le16_to_cpu(wavhd.bit_p_spl);
+ wavhd.data_length = le32_to_cpu(wavhd.data_length);
+
if(wavhd.format != 1) Die("Input is not a PCM WAV file");
#ifndef LP2CD
if (! (mods&MSPEED))
@@ -518,6 +556,11 @@
fprintf(stderr, "Playing Creative Labs Voice file ...\n");
memcpy((void*)&vochd, (void*)hd_buf, 20);
count = read(thefd, ((char*)&vochd)+20, sizeof(vochd) - 20);
+
+ vochd.BlockOffset = le16_to_cpu(vochd.BlockOffset);
+ vochd.Version = le16_to_cpu(vochd.Version);
+ vochd.IDCode = le16_to_cpu(vochd.IDCode);
+
fprintf(stderr, "Format version %d.%d\n", vochd.Version>>8,
vochd.Version&0xFF);
if (vochd.IDCode != (~vochd.Version+0x1234))
@@ -566,6 +609,9 @@
{
blockT8 tblock;
read(thefd, (char*)&tblock, sizeof(tblock));
+
+ tblock.TimeConstant = le16_to_cpu(tblock.TimeConstant);
+
if(tblock.PackMethod != 0) Die("Non PCM VOC block");
speed = 256000000/(65536 - tblock.TimeConstant);
bits = 8;
@@ -578,6 +624,10 @@
{
blockT9 tblock;
read(thefd, (char*)&tblock, sizeof(tblock));
+
+ tblock.SamplesPerSec = le32_to_cpu(tblock.SamplesPerSec);
+ tblock.Format = le16_to_cpu(tblock.Format);
+
if(tblock.Format != 0 && tblock.Format != 4)
Die("Non PCM VOC block");
speed = tblock.SamplesPerSec;
Index: bplaysrc/fmtheaders.h
===================================================================
RCS file: /home/kobras/cvsroot/debian/gramofile/bplaysrc/fmtheaders.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 fmtheaders.h
--- bplaysrc/fmtheaders.h 2001/05/05 13:52:25 1.1.1.1
+++ bplaysrc/fmtheaders.h 2005/01/31 15:54:06
@@ -4,43 +4,49 @@
#include <sys/types.h>
#include <inttypes.h>
+#ifdef __GNUC__
+# define PACKED(x) __attribute__((packed)) x
+#else
+# define PACKED(x) x
+#endif
+
/* Definitions for .VOC files */
#define VOC_MAGIC "Creative Voice File\032"
-#define DATALEN(bp) ((uint32_t)(bp.BlockLen[0]) | \
- ((uint32_t)(bp.BlockLen[1]) << 8) | \
- ((uint32_t)(bp.BlockLen[2]) << 16) )
+#define DATALEN(bp) ((u_int32_t)(bp.BlockLen[0]) | \
+ ((u_int32_t)(bp.BlockLen[1]) << 8) | \
+ ((u_int32_t)(bp.BlockLen[2]) << 16) )
typedef struct vochead {
- u_char Magic[20]; /* must be VOC_MAGIC */
- u_short BlockOffset; /* Offset to first block from top of file */
- u_short Version; /* VOC-file version */
- u_short IDCode; /* complement of version + 0x1234 */
+ u_int8_t Magic[20]; /* must be VOC_MAGIC */
+ u_int16_t BlockOffset; /* Offset to first block from top of file */
+ u_int16_t Version; /* VOC-file version */
+ u_int16_t IDCode; /* complement of version + 0x1234 */
} vochead;
typedef struct blockTC {
- u_char BlockID;
- u_char BlockLen[3]; /* low, mid, high byte of length of rest of block */
+ u_int8_t BlockID;
+ u_int8_t BlockLen[3]; /* low, mid, high byte of length of rest of
block */
} blockTC;
typedef struct blockT1 {
- u_char TimeConstant;
- u_char PackMethod;
+ u_int8_t TimeConstant;
+ u_int8_t PackMethod;
} blockT1;
typedef struct blockT8 {
- u_short TimeConstant;
- u_char PackMethod;
- u_char VoiceMode;
+ u_int16_t TimeConstant;
+ u_int8_t PackMethod;
+ u_int8_t VoiceMode;
} blockT8;
typedef struct blockT9 {
u_int SamplesPerSec;
- u_char BitsPerSample;
- u_char Channels;
- u_short Format;
- u_char reserved[4];
+ u_int8_t BitsPerSample;
+ u_int8_t Channels;
+ u_int16_t Format;
+ u_int8_t reserved[4];
} blockT9;
@@ -52,21 +58,21 @@
it works on all WAVE-file I have
*/
typedef struct wavhead {
- uint32_t main_chunk; /* 'RIFF' */
- uint32_t length; /* Length of rest of file */
- uint32_t chunk_type; /* 'WAVE' */
+ u_int32_t main_chunk; /* 'RIFF' */
+ u_int32_t length; /* Length of rest of file */
+ u_int32_t chunk_type; /* 'WAVE' */
- uint32_t sub_chunk; /* 'fmt ' */
- uint32_t sc_len; /* length of sub_chunk, =16 (rest of chunk) */
- u_short format; /* should be 1 for PCM-code */
- u_short modus; /* 1 Mono, 2 Stereo */
- uint32_t sample_fq; /* frequence of sample */
- uint32_t byte_p_sec;
- u_short byte_p_spl; /* samplesize; 1 or 2 bytes */
- u_short bit_p_spl; /* 8, 12 or 16 bit */
+ u_int32_t sub_chunk; /* 'fmt ' */
+ u_int32_t sc_len; /* length of sub_chunk, =16 (rest of chunk) */
+ u_int16_t format; /* should be 1 for PCM-code */
+ u_int16_t modus; /* 1 Mono, 2 Stereo */
+ u_int32_t sample_fq; /* frequence of sample */
+ u_int32_t byte_p_sec;
+ u_int16_t byte_p_spl; /* samplesize; 1 or 2 bytes */
+ u_int16_t bit_p_spl; /* 8, 12 or 16 bit */
- uint32_t data_chunk; /* 'data' */
- uint32_t data_length; /* samplecount (lenth of rest of block?)*/
+ u_int32_t data_chunk; /* 'data' */
+ u_int32_t data_length; /* samplecount (lenth of rest of block?)*/
} wavhead;
#endif
Index: bplaysrc/sndfunc.c
===================================================================
RCS file: /home/kobras/cvsroot/debian/gramofile/bplaysrc/sndfunc.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 sndfunc.c
--- bplaysrc/sndfunc.c 2001/05/05 14:07:15 1.1.1.2
+++ bplaysrc/sndfunc.c 2005/01/31 15:54:06
@@ -64,6 +64,9 @@
sync_audio();
/* Set the sample speed, size and stereoness */
+ /* We only use values of 8 and 16 for bits. This implies
+ * unsigned data for 8 bits, and little-endian signed for 16 bits.
+ */
if (ioctl(audio, SNDCTL_DSP_SAMPLESIZE, &bits) < 0)
ErrDie(AUDIO);
if (ioctl(audio, SNDCTL_DSP_STEREO, &stereo) < 0)