]> git.alsa-project.org Git - alsa-utils.git/commitdiff
various bugfixes
authorClemens Ladisch <clemens@ladisch.de>
Mon, 13 Sep 2004 07:04:53 +0000 (07:04 +0000)
committerClemens Ladisch <clemens@ladisch.de>
Mon, 13 Sep 2004 07:04:53 +0000 (07:04 +0000)
- don't parse -X option because such an option doesn't exist
- allow argument for --sleep-min option
- fix handling of .voc magic string
- fix handling of .voc files on big-endian machines
- remove superfluous "size" parameter from check_wavefile_space macro
- reallocate buffer only if needed in check_wavefile_space
- fix playback of >2GB .wav files
- skip over padding bytes in .wav files
- fix memory leak when playing .voc silence blocks
- fix file length when recording >2GB .wav files
- fix recording of >4GB files

aplay/aplay.c
aplay/formats.h

index 4bc792b3e66c1dda8f64e7d081d7e378c63aa6f9..4ee0fa193fc7a0a2a831fcc0b4c046cbb850a2a8 100644 (file)
@@ -305,7 +305,7 @@ enum {
 int main(int argc, char *argv[])
 {
        int option_index;
-       char *short_options = "hlLD:qt:c:f:r:d:s:MNF:A:X:R:T:B:vIPC";
+       char *short_options = "hlLD:qt:c:f:r:d:s:MNF:A:R:T:B:vIPC";
        static struct option long_options[] = {
                {"help", 0, 0, 'h'},
                {"version", 0, 0, OPT_VERSION},
@@ -318,7 +318,7 @@ int main(int argc, char *argv[])
                {"format", 1, 0, 'f'},
                {"rate", 1, 0, 'r'},
                {"duration", 1, 0 ,'d'},
-               {"sleep-min", 0, 0, 's'},
+               {"sleep-min", 1, 0, 's'},
                {"mmap", 0, 0, 'M'},
                {"nonblock", 0, 0, 'N'},
                {"period-time", 1, 0, 'F'},
@@ -602,12 +602,12 @@ static int test_vocfile(void *buffer)
 {
        VocHeader *vp = buffer;
 
-       if (strstr(vp->magic, VOC_MAGIC_STRING)) {
-               vocminor = vp->version & 0xFF;
-               vocmajor = vp->version / 256;
-               if (vp->version != (0x1233 - vp->coded_ver))
+       if (!memcmp(vp->magic, VOC_MAGIC_STRING, 20)) {
+               vocminor = LE_SHORT(vp->version) & 0xFF;
+               vocmajor = LE_SHORT(vp->version) / 256;
+               if (LE_SHORT(vp->version) != (0x1233 - LE_SHORT(vp->coded_ver)))
                        return -2;      /* coded version mismatch */
-               return vp->headerlen - sizeof(VocHeader);       /* 0 mostly */
+               return LE_SHORT(vp->headerlen) - sizeof(VocHeader);     /* 0 mostly */
        }
        return -1;              /* magic string fail */
 }
@@ -627,12 +627,13 @@ size_t test_wavefile_read(int fd, char *buffer, size_t *size, size_t reqsize, in
        return *size = reqsize;
 }
 
-#define check_wavefile_space(buffer, size, len, blimit) \
-       if (size + len > blimit) \
-               blimit = size + len; \
-       if ((buffer = realloc(buffer, blimit)) == NULL) { \
-               error("not enough memory"); \
-               exit(EXIT_FAILURE); \
+#define check_wavefile_space(buffer, len, blimit) \
+       if (len > blimit) { \
+               blimit = len; \
+               if ((buffer = realloc(buffer, blimit)) == NULL) { \
+                       error("not enough memory"); \
+                       exit(EXIT_FAILURE); \
+               } \
        }
 
 /*
@@ -654,22 +655,23 @@ static ssize_t test_wavefile(int fd, char *_buffer, size_t size)
        if (h->magic != WAV_RIFF || h->type != WAV_WAVE)
                return -1;
        if (size > sizeof(WaveHeader)) {
-               check_wavefile_space(buffer, size, size - sizeof(WaveHeader), blimit);
+               check_wavefile_space(buffer, size - sizeof(WaveHeader), blimit);
                memcpy(buffer, _buffer + sizeof(WaveHeader), size - sizeof(WaveHeader));
        }
        size -= sizeof(WaveHeader);
        while (1) {
-               check_wavefile_space(buffer, size, sizeof(WaveChunkHeader), blimit);
+               check_wavefile_space(buffer, sizeof(WaveChunkHeader), blimit);
                test_wavefile_read(fd, buffer, &size, sizeof(WaveChunkHeader), __LINE__);
                c = (WaveChunkHeader*)buffer;
                type = c->type;
                len = LE_INT(c->length);
+               len += len % 2;
                if (size > sizeof(WaveChunkHeader))
                        memmove(buffer, buffer + sizeof(WaveChunkHeader), size - sizeof(WaveChunkHeader));
                size -= sizeof(WaveChunkHeader);
                if (type == WAV_FMT)
                        break;
-               check_wavefile_space(buffer, size, len, blimit);
+               check_wavefile_space(buffer, len, blimit);
                test_wavefile_read(fd, buffer, &size, len, __LINE__);
                if (size > len)
                        memmove(buffer, buffer + len, size - len);
@@ -680,7 +682,7 @@ static ssize_t test_wavefile(int fd, char *_buffer, size_t size)
                error("unknown length of 'fmt ' chunk (read %u, should be %u at least)", len, (u_int)sizeof(WaveFmtBody));
                exit(EXIT_FAILURE);
        }
-       check_wavefile_space(buffer, size, len, blimit);
+       check_wavefile_space(buffer, len, blimit);
        test_wavefile_read(fd, buffer, &size, len, __LINE__);
        f = (WaveFmtBody*) buffer;
        if (LE_SHORT(f->format) != WAV_PCM_CODE) {
@@ -740,7 +742,7 @@ static ssize_t test_wavefile(int fd, char *_buffer, size_t size)
        while (1) {
                u_int type, len;
 
-               check_wavefile_space(buffer, size, sizeof(WaveChunkHeader), blimit);
+               check_wavefile_space(buffer, sizeof(WaveChunkHeader), blimit);
                test_wavefile_read(fd, buffer, &size, sizeof(WaveChunkHeader), __LINE__);
                c = (WaveChunkHeader*)buffer;
                type = c->type;
@@ -749,14 +751,15 @@ static ssize_t test_wavefile(int fd, char *_buffer, size_t size)
                        memmove(buffer, buffer + sizeof(WaveChunkHeader), size - sizeof(WaveChunkHeader));
                size -= sizeof(WaveChunkHeader);
                if (type == WAV_DATA) {
-                       if (len < pbrec_count)
+                       if (len < pbrec_count && len < 0x7ffffffe)
                                pbrec_count = len;
                        if (size > 0)
                                memcpy(_buffer, buffer, size);
                        free(buffer);
                        return size;
                }
-               check_wavefile_space(buffer, size, len, blimit);
+               len += len % 2;
+               check_wavefile_space(buffer, len, blimit);
                test_wavefile_read(fd, buffer, &size, len, __LINE__);
                if (size > len)
                        memmove(buffer, buffer + len, size - len);
@@ -1294,6 +1297,7 @@ static void voc_write_silence(unsigned x)
                }
                x -= l;
        }
+       free(buf);
 }
 
 static void voc_pcm_flush(void)
@@ -1562,11 +1566,10 @@ static void begin_voc(int fd, size_t cnt)
        VocVoiceData vd;
        VocExtBlock eb;
 
-       strncpy(vh.magic, VOC_MAGIC_STRING, 20);
-       vh.magic[19] = 0x1A;
-       vh.headerlen = sizeof(VocHeader);
-       vh.version = VOC_ACTUAL_VERSION;
-       vh.coded_ver = 0x1233 - VOC_ACTUAL_VERSION;
+       memcpy(vh.magic, VOC_MAGIC_STRING, 20);
+       vh.headerlen = LE_SHORT(sizeof(VocHeader));
+       vh.version = LE_SHORT(VOC_ACTUAL_VERSION);
+       vh.coded_ver = LE_SHORT(0x1233 - VOC_ACTUAL_VERSION);
 
        if (write(fd, &vh, sizeof(VocHeader)) != sizeof(VocHeader)) {
                error("write error");
@@ -1581,7 +1584,7 @@ static void begin_voc(int fd, size_t cnt)
                        error("write error");
                        exit(EXIT_FAILURE);
                }
-               eb.tc = (u_short) (65536 - 256000000L / (hwparams.rate << 1));
+               eb.tc = LE_SHORT(65536 - 256000000L / (hwparams.rate << 1));
                eb.pack = 0;
                eb.mode = 1;
                if (write(fd, &eb, sizeof(VocExtBlock)) != sizeof(VocExtBlock)) {
@@ -1743,15 +1746,16 @@ static void end_wave(int fd)
 {                              /* only close output */
        WaveChunkHeader cd;
        off64_t length_seek;
+       off64_t filelen;
        u_int rifflen;
        
        length_seek = sizeof(WaveHeader) +
                      sizeof(WaveChunkHeader) +
                      sizeof(WaveFmtBody);
        cd.type = WAV_DATA;
-       cd.length = fdcount > 0x7fffffff ? 0x7fffffff : LE_INT(fdcount);
-       rifflen = fdcount + 2*sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + 4;
-       rifflen = rifflen > 0x7fffffff ? 0x7fffffff : LE_INT(rifflen);
+       cd.length = fdcount > 0x7fffffff ? LE_INT(0x7fffffff) : LE_INT(fdcount);
+       filelen = fdcount + 2*sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + 4;
+       rifflen = filelen > 0x7fffffff ? LE_INT(0x7fffffff) : LE_INT(filelen);
        if (lseek64(fd, 4, SEEK_SET) == 4)
                write(fd, &rifflen, 4);
        if (lseek64(fd, length_seek, SEEK_SET) == length_seek)
@@ -1856,9 +1860,7 @@ void capture_go(int fd, off64_t count, int rtype, char *name)
 
        do {
                for (cur = count; cur > 0; cur -= r) {
-                       c = cur;
-                       if (c > chunk_bytes)
-                               c = chunk_bytes;
+                       c = (cur <= chunk_bytes) ? cur : chunk_bytes;
                        c = c * 8 / bits_per_frame;
                        if ((size_t)(r = pcm_read(audiobuf, c)) != c)
                                break;
index f61db3b0e8de700916d7db7a28597e5e689d1289..2c4f724f0f9ae20ced01445190e3df093d953a7b 100644 (file)
@@ -6,7 +6,7 @@
 
 /* Definitions for .VOC files */
 
-#define VOC_MAGIC_STRING       "Creative Voice File\0x1A"
+#define VOC_MAGIC_STRING       "Creative Voice File\x1A"
 #define VOC_ACTUAL_VERSION     0x010A
 #define VOC_SAMPLESIZE         8