File 70-endian-fixes.dpatch of Package gramofile
# 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.
# Merged with endianness patch by Tom Harvey <TomHarvey@IndustryFigure.com>
# [dk]
Index: bplaysrc/bplay.c
===================================================================
--- bplaysrc/bplay.c.orig 2012-04-20 16:01:14.461139421 +0200
+++ bplaysrc/bplay.c 2012-04-20 16:03:12.609289818 +0200
@@ -30,6 +30,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"
@@ -287,23 +311,26 @@ int main(int argc, char *argv[])
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:
@@ -333,9 +360,9 @@ int main(int argc, char *argv[])
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);
@@ -346,10 +373,10 @@ int main(int argc, char *argv[])
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);
@@ -473,6 +500,17 @@ long bcount = 0, bjump = 0;
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))
@@ -515,6 +553,11 @@ void playvoc(int thefd, char hd_buf[20])
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))
@@ -563,6 +606,9 @@ void playvoc(int thefd, char hd_buf[20])
{
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;
@@ -575,6 +621,10 @@ void playvoc(int thefd, char hd_buf[20])
{
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
===================================================================
--- bplaysrc/fmtheaders.h.orig 1997-02-10 21:32:20.000000000 +0100
+++ bplaysrc/fmtheaders.h 2012-04-20 16:02:36.361164344 +0200
@@ -3,44 +3,50 @@
#include <sys/types.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) ((u_long)(bp.BlockLen[0]) | \
- ((u_long)(bp.BlockLen[1]) << 8) | \
- ((u_long)(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 */
-} vochead;
+ 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 */
+} PACKED(vochead);
typedef struct blockTC {
- u_char BlockID;
- u_char BlockLen[3]; /* low, mid, high byte of length of rest of block */
-} blockTC;
+ u_int8_t BlockID;
+ u_int8_t BlockLen[3]; /* low, mid, high byte of length of rest of block */
+} PACKED(blockTC);
typedef struct blockT1 {
- u_char TimeConstant;
- u_char PackMethod;
-} blockT1;
+ u_int8_t TimeConstant;
+ u_int8_t PackMethod;
+} PACKED(blockT1);
typedef struct blockT8 {
- u_short TimeConstant;
- u_char PackMethod;
- u_char VoiceMode;
-} blockT8;
+ u_int16_t TimeConstant;
+ u_int8_t PackMethod;
+ u_int8_t VoiceMode;
+} PACKED(blockT8);
typedef struct blockT9 {
- u_int SamplesPerSec;
- u_char BitsPerSample;
- u_char Channels;
- u_short Format;
- u_char reserved[4];
-} blockT9;
+ u_int32_t SamplesPerSec;
+ u_int8_t BitsPerSample;
+ u_int8_t Channels;
+ u_int16_t Format;
+ u_int8_t reserved[4];
+} PACKED(blockT9);
@@ -51,21 +57,21 @@ typedef struct blockT9 {
it works on all WAVE-file I have
*/
typedef struct wavhead {
- u_long main_chunk; /* 'RIFF' */
- u_long length; /* Length of rest of file */
- u_long chunk_type; /* 'WAVE' */
-
- u_long sub_chunk; /* 'fmt ' */
- u_long 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 */
- u_long sample_fq; /* frequence of sample */
- u_long byte_p_sec;
- u_short byte_p_spl; /* samplesize; 1 or 2 bytes */
- u_short bit_p_spl; /* 8, 12 or 16 bit */
-
- u_long data_chunk; /* 'data' */
- u_long data_length; /* samplecount (lenth of rest of block?)*/
-} wavhead;
+ u_int32_t main_chunk; /* 'RIFF' */
+ u_int32_t length; /* Length of rest of file */
+ u_int32_t chunk_type; /* 'WAVE' */
+
+ 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 */
+
+ u_int32_t data_chunk; /* 'data' */
+ u_int32_t data_length; /* samplecount (lenth of rest of block?)*/
+} PACKED(wavhead);
#endif
Index: bplaysrc/sndfunc.c
===================================================================
--- bplaysrc/sndfunc.c.orig 2012-04-20 16:01:14.446139781 +0200
+++ bplaysrc/sndfunc.c 2012-04-20 16:01:14.494138625 +0200
@@ -66,6 +66,9 @@ void snd_parm(int speed, int bits, int s
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)
Index: endian.c
===================================================================
--- endian.c.orig 2000-03-28 23:07:25.000000000 +0200
+++ endian.c 2012-04-20 16:01:14.494138625 +0200
@@ -24,10 +24,10 @@ SwapTwo (short w)
return (tmp);
}
-u_long
-SwapFourBytes (u_long dw)
+u_int32_t
+SwapFourBytes (u_int32_t dw)
{
- register u_long tmp;
+ register u_int32_t tmp;
tmp = (dw & 0x000000FF);
tmp = ((dw & 0x0000FF00) >> 0x08) | (tmp << 0x08);
tmp = ((dw & 0x00FF0000) >> 0x10) | (tmp << 0x08);
Index: endian.h
===================================================================
--- endian.h.orig 2012-04-20 16:01:14.469139227 +0200
+++ endian.h 2012-04-20 16:01:14.494138625 +0200
@@ -4,8 +4,10 @@
#ifndef _GETBIG
#define _GETBIG 1
+#include <sys/types.h>
+
extern u_short SwapTwoBytes (u_short);
-extern u_long SwapFourBytes (u_long);
+extern u_int32_t SwapFourBytes (u_int32_t);
extern sample_t SwapSample (sample_t);
/* macro to swap endianness of values in a sample_t with */
Index: fmtheaders.h
===================================================================
--- fmtheaders.h.orig 2000-03-28 23:07:26.000000000 +0200
+++ fmtheaders.h 2012-04-20 16:02:18.449596395 +0200
@@ -3,54 +3,50 @@
#include <sys/types.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) ((u_long)(bp.BlockLen[0]) | \
- ((u_long)(bp.BlockLen[1]) << 8) | \
- ((u_long)(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 */
- }
-vochead;
-
-typedef struct blockTC
- {
- u_char BlockID;
- u_char BlockLen[3]; /* low, mid, high byte of length of rest of block */
- }
-blockTC;
-
-typedef struct blockT1
- {
- u_char TimeConstant;
- u_char PackMethod;
- }
-blockT1;
-
-typedef struct blockT8
- {
- u_short TimeConstant;
- u_char PackMethod;
- u_char VoiceMode;
- }
-blockT8;
-
-typedef struct blockT9
- {
- u_int SamplesPerSec;
- u_char BitsPerSample;
- u_char Channels;
- u_short Format;
- u_char reserved[4];
- }
-blockT9;
+#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_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 */
+} PACKED(vochead);
+
+typedef struct blockTC {
+ u_int8_t BlockID;
+ u_int8_t BlockLen[3]; /* low, mid, high byte of length of rest of block */
+} PACKED(blockTC);
+
+typedef struct blockT1 {
+ u_int8_t TimeConstant;
+ u_int8_t PackMethod;
+} PACKED(blockT1);
+
+typedef struct blockT8 {
+ u_int16_t TimeConstant;
+ u_int8_t PackMethod;
+ u_int8_t VoiceMode;
+} PACKED(blockT8);
+
+typedef struct blockT9 {
+ u_int32_t SamplesPerSec;
+ u_int8_t BitsPerSample;
+ u_int8_t Channels;
+ u_int16_t Format;
+ u_int8_t reserved[4];
+} PACKED(blockT9);
@@ -59,25 +55,23 @@ blockT9;
/* it's in chunks like .voc and AMIGA iff, but my source say there
are in only in this combination, so I combined them in one header;
it works on all WAVE-file I have
- */
-typedef struct wavhead
- {
- u_long main_chunk; /* 'RIFF' */
- u_long length; /* Length of rest of file */
- u_long chunk_type; /* 'WAVE' */
-
- u_long sub_chunk; /* 'fmt ' */
- u_long 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 */
- u_long sample_fq; /* frequence of sample */
- u_long byte_p_sec;
- u_short byte_p_spl; /* samplesize; 1 or 2 bytes */
- u_short bit_p_spl; /* 8, 12 or 16 bit */
-
- u_long data_chunk; /* 'data' */
- u_long data_length; /* samplecount (lenth of rest of block?) */
- }
-wavhead;
+*/
+typedef struct wavhead {
+ u_int32_t main_chunk; /* 'RIFF' */
+ u_int32_t length; /* Length of rest of file */
+ u_int32_t chunk_type; /* 'WAVE' */
+
+ 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 */
+
+ u_int32_t data_chunk; /* 'data' */
+ u_int32_t data_length; /* samplecount (lenth of rest of block?)*/
+} PACKED(wavhead);
#endif