Update to latest tinyalsa
authorSimon Wilson <simonwilson@google.com>
Wed, 16 May 2012 00:37:19 +0000 (17:37 -0700)
committerSimon Wilson <simonwilson@google.com>
Wed, 16 May 2012 00:37:19 +0000 (17:37 -0700)
2581a1e add error check for pcm_start
6a52f2c mixer: add missing include for sys/ioctl.h
9eba533 tinyplay: add multichannel support
fba29e6 tinycap: Fix byte_rate and block_align values

Change-Id: Icbee0a8c1e101234ac55ba8494c74b442f215576

mixer.c
pcm.c
tinycap.c
tinyplay.c

diff --git a/mixer.c b/mixer.c
index 4a39a4317dc069ad802a80ed13dae3653d5ff16e..9514528083daf1ff739bb8c9ad701af111f36754 100644 (file)
--- a/mixer.c
+++ b/mixer.c
@@ -34,6 +34,8 @@
 #include <errno.h>
 #include <ctype.h>
 
+#include <sys/ioctl.h>
+
 #include <linux/ioctl.h>
 #define __force
 #define __bitwise
diff --git a/pcm.c b/pcm.c
index 6d4dbd567d61e629db20fda78ccc39946b9aabc7..4e9133acb3514ad05b111734075aeab0f736857f 100644 (file)
--- a/pcm.c
+++ b/pcm.c
@@ -415,7 +415,10 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count)
 
     for (;;) {
         if (!pcm->running) {
-            pcm_start(pcm);
+            if (pcm_start(pcm) < 0) {
+                fprintf(stderr, "start error");
+                return -errno;
+            }
         }
         if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
             pcm->running = 0;
index dcc238c1d5b2a18aca064a83ebb9929528c6a71e..d5633098d6e63bccbf4d7b7b095de95f333e7712 100644 (file)
--- a/tinycap.c
+++ b/tinycap.c
@@ -136,9 +136,9 @@ int main(int argc, char **argv)
     header.audio_format = FORMAT_PCM;
     header.num_channels = channels;
     header.sample_rate = rate;
+    header.bits_per_sample = bits;
     header.byte_rate = (header.bits_per_sample / 8) * channels * rate;
     header.block_align = channels * (header.bits_per_sample / 8);
-    header.bits_per_sample = bits;
     header.data_id = ID_DATA;
 
     /* leave enough room for header */
index 4d257e768cccc1488775c2c1f5b7d7ef832c1eb5..3f76cc6470ffbde867f6d04224639522c9b3b6fd 100644 (file)
 #define ID_FMT  0x20746d66
 #define ID_DATA 0x61746164
 
-#define FORMAT_PCM 1
-
-struct wav_header {
+struct riff_wave_header {
     uint32_t riff_id;
     uint32_t riff_sz;
-    uint32_t riff_fmt;
-    uint32_t fmt_id;
-    uint32_t fmt_sz;
+    uint32_t wave_id;
+};
+
+struct chunk_header {
+    uint32_t id;
+    uint32_t sz;
+};
+
+struct chunk_fmt {
     uint16_t audio_format;
     uint16_t num_channels;
     uint32_t sample_rate;
     uint32_t byte_rate;
     uint16_t block_align;
     uint16_t bits_per_sample;
-    uint32_t data_id;
-    uint32_t data_sz;
 };
 
 void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
@@ -61,11 +63,15 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in
 int main(int argc, char **argv)
 {
     FILE *file;
-    struct wav_header header;
+    struct riff_wave_header riff_wave_header;
+    struct chunk_header chunk_header;
+    struct chunk_fmt chunk_fmt;
     unsigned int device = 0;
     unsigned int card = 0;
     unsigned int period_size = 1024;
     unsigned int period_count = 4;
+    char *filename;
+    int more_chunks = 1;
 
     if (argc < 2) {
         fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-p period_size]"
@@ -73,12 +79,41 @@ int main(int argc, char **argv)
         return 1;
     }
 
-    file = fopen(argv[1], "rb");
+    filename = argv[1];
+    file = fopen(filename, "rb");
     if (!file) {
-        fprintf(stderr, "Unable to open file '%s'\n", argv[1]);
+        fprintf(stderr, "Unable to open file '%s'\n", filename);
+        return 1;
+    }
+
+    fread(&riff_wave_header, sizeof(riff_wave_header), 1, file);
+    if ((riff_wave_header.riff_id != ID_RIFF) ||
+        (riff_wave_header.wave_id != ID_WAVE)) {
+        fprintf(stderr, "Error: '%s' is not a riff/wave file\n", filename);
+        fclose(file);
         return 1;
     }
 
+    do {
+        fread(&chunk_header, sizeof(chunk_header), 1, file);
+
+        switch (chunk_header.id) {
+        case ID_FMT:
+            fread(&chunk_fmt, sizeof(chunk_fmt), 1, file);
+            /* If the format header is larger, skip the rest */
+            if (chunk_header.sz > sizeof(chunk_fmt))
+                fseek(file, chunk_header.sz - sizeof(chunk_fmt), SEEK_CUR);
+            break;
+        case ID_DATA:
+            /* Stop looking for chunks */
+            more_chunks = 0;
+            break;
+        default:
+            /* Unknown chunk, skip bytes */
+            fseek(file, chunk_header.sz, SEEK_CUR);
+        }
+    } while (more_chunks);
+
     /* parse command line arguments */
     argv += 2;
     while (*argv) {
@@ -106,20 +141,8 @@ int main(int argc, char **argv)
             argv++;
     }
 
-    fread(&header, sizeof(struct wav_header), 1, file);
-
-    if ((header.riff_id != ID_RIFF) ||
-        (header.riff_fmt != ID_WAVE) ||
-        (header.fmt_id != ID_FMT) ||
-        (header.audio_format != FORMAT_PCM) ||
-        (header.fmt_sz != 16)) {
-        fprintf(stderr, "Error: '%s' is not a PCM riff/wave file\n", argv[1]);
-        fclose(file);
-        return 1;
-    }
-
-    play_sample(file, card, device, header.num_channels, header.sample_rate,
-                header.bits_per_sample, period_size, period_count);
+    play_sample(file, card, device, chunk_fmt.num_channels, chunk_fmt.sample_rate,
+                chunk_fmt.bits_per_sample, period_size, period_count);
 
     fclose(file);