ced20ee92d
add WITHOUT_NLS knob fix coredumping on 64bit platforms [1] make X-CD-Roast much more nicer in accepting some wav files [2] remove autoconf dependency bump PORTREVISION Inspired by: http://www.xcdroast.org/xcdr098/patches/64bit_gsize.patch [1] Taken from: http://www.xcdroast.org/xcdr098/patches/wav.patch [2]
354 lines
9.1 KiB
Text
354 lines
9.1 KiB
Text
--- src/main.h.orig Tue Apr 6 13:37:32 2004
|
|
+++ src/main.h Mon Apr 5 15:44:41 2004
|
|
@@ -175,8 +175,7 @@
|
|
void wavplay_frontend(GtkWidget *widget);
|
|
void wavplay_dodouble();
|
|
|
|
-gint is_std_wav_file(guchar *hdr);
|
|
-gint is_in_cd_quality(guchar *hdr);
|
|
+off_t is_std_wav_file(int f, off_t *offset);
|
|
|
|
void dodebug(gint debuglevel, gchar *fmt, ...);
|
|
void dolog(gint loglevel, gchar *fmt, ...);
|
|
--- src/wav_id.c.orig Tue Apr 6 13:37:53 2004
|
|
+++ src/wav_id.c Mon Apr 5 15:44:38 2004
|
|
@@ -5,6 +5,11 @@
|
|
machine-independent (work both on big and little endian)
|
|
code to check if we have valid wavheader that is configured
|
|
for cd-quality (16 bit, stereo, 44.1kHz)
|
|
+
|
|
+ 01.04.04 steve wahl
|
|
+
|
|
+ Do correct RIFF parsing, don't assume a static header style.
|
|
+ Code borrowed from cdrecord.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
@@ -13,62 +18,147 @@
|
|
|
|
#include "largefile.h"
|
|
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <unistd.h>
|
|
#include <string.h>
|
|
#include <glib.h>
|
|
#include "xcdroast.h"
|
|
|
|
+typedef struct {
|
|
+ guchar ckid[4];
|
|
+ guchar cksize[4];
|
|
+} chunk_t;
|
|
+
|
|
+typedef struct {
|
|
+ guchar wave[4];
|
|
+} riff_chunk;
|
|
+
|
|
+typedef struct {
|
|
+ guchar fmt_tag[2];
|
|
+ guchar channels[2];
|
|
+ guchar sample_rate[4];
|
|
+ guchar av_byte_rate[4];
|
|
+ guchar block_size[2];
|
|
+ guchar bits_per_sample[2];
|
|
+} fmt_chunk;
|
|
+
|
|
+#define WAV_RIFF_MAGIC "RIFF" /* Magic for file format */
|
|
+#define WAV_WAVE_MAGIC "WAVE" /* Magic for Waveform Audio */
|
|
+#define WAV_FMT_MAGIC "fmt " /* Start of Waveform format */
|
|
+#define WAV_DATA_MAGIC "data" /* Start of data chunk */
|
|
+#define WAV_FORMAT_PCM 0x0001 /* Linear PCM format */
|
|
+#define WAV_FORMAT_ULAW 0x0101 /* American ISDN Telephonie */
|
|
+#define WAV_FORMAT_ALAW 0x0102 /* International ISDN Tel. */
|
|
+#define WAV_FORMAT_ADPCM 0x0103 /* ADPCM format */
|
|
+
|
|
+#define le_a_to_u_short(a) ((unsigned short) \
|
|
+ ((((unsigned char*) a)[0] & 0xFF) | \
|
|
+ (((unsigned char*) a)[1] << 8 & 0xFF00)))
|
|
+
|
|
+#ifdef __STDC__
|
|
+#define le_a_to_u_long(a) ((unsigned long) \
|
|
+ ((((unsigned char*) a)[0] & 0xFF) | \
|
|
+ (((unsigned char*) a)[1] << 8 & 0xFF00) | \
|
|
+ (((unsigned char*) a)[2] << 16 & 0xFF0000) | \
|
|
+ (((unsigned char*) a)[3] << 24 & 0xFF000000UL)))
|
|
+#else
|
|
+#define le_a_to_u_long(a) ((unsigned long) \
|
|
+ ((((unsigned char*) a)[0] & 0xFF) | \
|
|
+ (((unsigned char*) a)[1] << 8 & 0xFF00) | \
|
|
+ (((unsigned char*) a)[2] << 16 & 0xFF0000) | \
|
|
+ (((unsigned char*) a)[3] << 24 & 0xFF000000)))
|
|
+#endif
|
|
+
|
|
/* check if valid wav-header */
|
|
/* endian independent version */
|
|
-/* return 1 if true, 0 if not */
|
|
-
|
|
-gint is_std_wav_file(guchar *hdr) {
|
|
-gchar tmp[MAXLINE];
|
|
-guint wFormatTag;
|
|
-guint fmtOffset;
|
|
-
|
|
- strncpy(tmp,(char *) hdr+0,4);
|
|
- if (strncmp(tmp,"RIFF",4) != 0)
|
|
- return 0;
|
|
-
|
|
- strncpy(tmp,(char *) hdr+8,4);
|
|
- if (strncmp(tmp,(char *)"WAVE",4) != 0)
|
|
- return 0;
|
|
-
|
|
- strncpy(tmp,(char *) hdr+12,4);
|
|
- if (strncmp(tmp,(char *)"fmt ",4) != 0)
|
|
- return 0;
|
|
-
|
|
- fmtOffset = (hdr[19]<<24) + (hdr[18]<<16) + (hdr[17]<<8) + hdr[16];
|
|
- strncpy(tmp,(char *) hdr+20+fmtOffset,4);
|
|
- if (strncmp(tmp,(char *)"data",4) != 0)
|
|
- return 0;
|
|
-
|
|
- wFormatTag = (hdr[21] << 8) + hdr[20];
|
|
- if (wFormatTag != 1)
|
|
- return 0;
|
|
-
|
|
- return 1;
|
|
+/* return number of bytes if valid, 0 if not */
|
|
+/* if offset is non NULL, place offset in file to base of wave data there */
|
|
+/* leaves file pointer at begining of wave data if valid */
|
|
+
|
|
+off_t is_std_wav_file(gint f, off_t *offset)
|
|
+{
|
|
+ chunk_t chunk;
|
|
+ riff_chunk riff;
|
|
+ fmt_chunk fmt;
|
|
+ struct stat sb;
|
|
+ off_t cursor;
|
|
+ gint gotFormat;
|
|
+ mode_t mode;
|
|
+ off_t size;
|
|
+
|
|
+ /*
|
|
+ * First check if a bad guy tries to call wavsize()
|
|
+ * with an unappropriate file descriptor.
|
|
+ * return 0 in this case.
|
|
+ */
|
|
+
|
|
+ if (isatty(f))
|
|
+ return (0);
|
|
+ if (fstat(f, &sb) < 0)
|
|
+ return (0);
|
|
+ mode = sb.st_mode & S_IFMT;
|
|
+ if (!S_ISREG(mode) && !S_ISBLK(mode) && !S_ISCHR(mode))
|
|
+ return (0);
|
|
+
|
|
+ cursor = (off_t)0;
|
|
+ lseek(f, cursor, SEEK_SET);
|
|
+ gotFormat = FALSE;
|
|
+
|
|
+ for (;;) {
|
|
+ if (read(f, &chunk, sizeof (chunk)) != sizeof (chunk))
|
|
+ goto err;
|
|
+ size = (off_t)le_a_to_u_long(chunk.cksize);
|
|
+
|
|
+ if (strncmp((char *)chunk.ckid, WAV_RIFF_MAGIC, 4) == 0) {
|
|
+ /*
|
|
+ * We found (first) RIFF header. Check if a WAVE
|
|
+ * magic follows. Set up size to be able to skip
|
|
+ * past this header.
|
|
+ */
|
|
+ if (read(f, &riff, sizeof (riff)) != sizeof (riff))
|
|
+ goto err;
|
|
+ if (strncmp((char *)riff.wave, WAV_WAVE_MAGIC, 4) != 0)
|
|
+ goto err;
|
|
+ size = (off_t)sizeof (riff);
|
|
+
|
|
+ } else if (strncmp((char *)chunk.ckid, WAV_FMT_MAGIC, 4) == 0) {
|
|
+ /*
|
|
+ * We found WAVE "fmt " header. Check size (if it is
|
|
+ * valid for a WAVE file) and coding whether it is
|
|
+ * useable for a CD.
|
|
+ */
|
|
+ if (size < (off_t)sizeof (fmt)) goto err;
|
|
+ if (sizeof (fmt) != read(f, &fmt, sizeof (fmt))) goto err;
|
|
+ if (le_a_to_u_short(fmt.channels) != 2 ||
|
|
+ le_a_to_u_long(fmt.sample_rate) != 44100 ||
|
|
+ le_a_to_u_short(fmt.bits_per_sample) != 16) {
|
|
+ goto err;
|
|
+ }
|
|
+ gotFormat = TRUE;
|
|
+
|
|
+ } else if (strncmp((char *)chunk.ckid, WAV_DATA_MAGIC, 4) == 0) {
|
|
+ /*
|
|
+ * We found WAVE "data" header. This contains the
|
|
+ * size value of the audio part.
|
|
+ */
|
|
+ if (!gotFormat) {
|
|
+ goto err;
|
|
+ }
|
|
+ if ((cursor + size + sizeof (chunk)) > sb.st_size)
|
|
+ size = sb.st_size - (cursor + sizeof (chunk));
|
|
+ if (offset)
|
|
+ *offset = cursor + sizeof (chunk) ;
|
|
+ return (size);
|
|
+ }
|
|
+ cursor += size + sizeof (chunk);
|
|
+ lseek(f, cursor, SEEK_SET); /* Skip over current chunk */
|
|
+ }
|
|
+err:
|
|
+ lseek(f, (off_t)0L, SEEK_SET);
|
|
+ return (0);
|
|
}
|
|
|
|
|
|
-/* check if wav-file is in cd-quality */
|
|
-/* endian independent version */
|
|
-/* return 1 if true, 0 if not */
|
|
-
|
|
-gint is_in_cd_quality(guchar *hdr) {
|
|
-guint nChannels;
|
|
-guint wBitsPerSample;
|
|
-guint nSamplesPerSec;
|
|
-
|
|
- nChannels = (hdr[23] << 8) + hdr[22];
|
|
- wBitsPerSample = (hdr[35] << 8) + hdr[34];
|
|
- nSamplesPerSec = (hdr[27]<<24) + (hdr[26]<<16) + (hdr[25]<<8) + hdr[24];
|
|
-
|
|
- if (nChannels != 2 || wBitsPerSample != 16 ||
|
|
- nSamplesPerSec != 44100)
|
|
- return 0;
|
|
-
|
|
- return 1;
|
|
-}
|
|
|
|
|
|
--- src/wavplay.c.orig Tue Apr 6 13:38:20 2004
|
|
+++ src/wavplay.c Mon Apr 5 15:45:07 2004
|
|
@@ -64,13 +64,12 @@
|
|
#include <dmedia/audio.h>
|
|
#endif
|
|
|
|
-static guchar waveHdr[44];
|
|
+static off_t waveBase ;
|
|
static gint abuf_size;
|
|
static guchar *audiobuf;
|
|
|
|
gint read_line(gint fd, gchar *ptr, gint maxlen);
|
|
-gint is_std_wav_file(guchar *hdr);
|
|
-gint is_in_cd_quality(guchar *hdr);
|
|
+off_t is_std_wav_file(int f, off_t *offset);
|
|
|
|
|
|
#if defined(linux) || defined(__FreeBSD__)
|
|
@@ -747,7 +746,6 @@
|
|
gint oldtick = 0;
|
|
off_t bytessofar = 0;
|
|
off_t totalbytes;
|
|
-struct stat stat_buf;
|
|
gint min,sec;
|
|
gchar keybuffer[MAXLINE];
|
|
#if !(defined(linux))
|
|
@@ -830,20 +828,11 @@
|
|
}
|
|
|
|
/* get filesize */
|
|
- fstat(fd, &stat_buf);
|
|
- totalbytes = (off_t) (stat_buf.st_size - (off_t)sizeof(waveHdr));
|
|
-
|
|
- read(fd, &waveHdr, sizeof(waveHdr));
|
|
+ totalbytes = is_std_wav_file(fd, &waveBase) ;
|
|
|
|
/* is it a wav-file? */
|
|
- if (!is_std_wav_file(waveHdr)) {
|
|
- g_warning("No valid wavfile\n");
|
|
- exit(0);
|
|
- }
|
|
-
|
|
- /* is it in cd-quality? */
|
|
- if (!is_in_cd_quality(waveHdr)) {
|
|
- g_warning("wavfile not in cd-quality\n");
|
|
+ if (totalbytes == 0) {
|
|
+ g_warning("No valid wavfile, or not in cd-quality\n");
|
|
exit(0);
|
|
}
|
|
|
|
@@ -871,7 +860,7 @@
|
|
if (guimode && (read_line(STDIN_FILENO,keybuffer,MAXLINE) > 0)) {
|
|
/* stop command */
|
|
if (g_strncasecmp(keybuffer,"stop",4) == 0) {
|
|
- lseek(fd, sizeof(waveHdr), SEEK_SET);
|
|
+ lseek(fd, waveBase, SEEK_SET);
|
|
bytessofar = 0;
|
|
tick = 0;
|
|
doplay = 0;
|
|
@@ -895,7 +884,7 @@
|
|
if (g_strncasecmp(keybuffer,"set",3) == 0) {
|
|
tick = atoi(keybuffer+3);
|
|
bytessofar = (off_t)tick *CDDAFRAME*75;
|
|
- lseek(fd, (off_t)sizeof(waveHdr)+bytessofar,
|
|
+ lseek(fd, waveBase+bytessofar,
|
|
SEEK_SET);
|
|
g_print("%s%d\n",doplay?"play":"stop",tick);
|
|
fflush(stdout);
|
|
@@ -911,7 +900,15 @@
|
|
if (doplay) {
|
|
|
|
/* read from wav-file */
|
|
- l = read(fd, audiobuf, abuf_size);
|
|
+ /* but only up until we reach totalbytes */
|
|
+ l = totalbytes - bytessofar ;
|
|
+ if (l > abuf_size)
|
|
+ l = abuf_size ;
|
|
+ if (l < 0)
|
|
+ l = 0 ;
|
|
+
|
|
+ if (l > 0)
|
|
+ l = read(fd, audiobuf, l);
|
|
if (l > 0) {
|
|
#if !(defined(linux))
|
|
/* turn byte order only on non linux platforms */
|
|
@@ -945,7 +942,7 @@
|
|
exit(-1);
|
|
}
|
|
#endif
|
|
- bytessofar+=(off_t)abuf_size;
|
|
+ bytessofar+=(off_t)l;
|
|
|
|
} else {
|
|
/* read error on wav-file */
|
|
@@ -958,7 +955,7 @@
|
|
doplay = 0;
|
|
if (guimode) {
|
|
/* roll back */
|
|
- lseek(fd, sizeof(waveHdr), SEEK_SET);
|
|
+ lseek(fd, waveBase, SEEK_SET);
|
|
bytessofar = 0;
|
|
tick = 0;
|
|
g_print("done%d\n",tick);
|
|
--- src/xtools.c.orig Tue Apr 6 13:38:49 2004
|
|
+++ src/xtools.c Mon Apr 5 15:44:44 2004
|
|
@@ -1851,7 +1851,6 @@
|
|
/* return 1 if, 0 if not */
|
|
|
|
gint check_wav_file(gchar *wavname) {
|
|
-guchar waveHdr[44];
|
|
gint fd;
|
|
|
|
fd = open (wavname, O_RDONLY, 0);
|
|
@@ -1859,16 +1858,8 @@
|
|
return 0;
|
|
}
|
|
|
|
- read(fd, &waveHdr, sizeof(waveHdr));
|
|
-
|
|
- if (!is_std_wav_file(waveHdr)) {
|
|
- /* no wav at all */
|
|
- close(fd);
|
|
- return 0;
|
|
- }
|
|
-
|
|
- /* is it in cd-quality? */
|
|
- if (!is_in_cd_quality(waveHdr)) {
|
|
+ if (!is_std_wav_file(fd, NULL)) {
|
|
+ /* no wav at all or not cd-quality */
|
|
close(fd);
|
|
return 0;
|
|
}
|