WAV header construction in tinyalsa
authorShivam Garg <garg.shivam@samsung.com>
Fri, 8 Sep 2017 11:48:34 +0000 (20:48 +0900)
committerShivam Garg <garg.shivam@samsung.com>
Mon, 18 Sep 2017 14:03:32 +0000 (23:03 +0900)
In pcm_open , while opening pcm device with PCM_IN flag, the wav header is written to the first buffer which is enqueued for getting captured data.

Moved definitions little->big endian and vice versa converting functions to pcm.h so that there is no need for reimplementing those in tinyalsa.c

framework/src/tinyalsa/tinyalsa.c
os/audio/pcm_decode.c
os/include/tinyara/audio/pcm.h

index 26f6c47..071d258 100644 (file)
@@ -66,6 +66,7 @@
 
 #include <tinyara/audio/audio.h>
 #include <tinyalsa/tinyalsa.h>
+#include <tinyara/audio/pcm.h>
 
 #define MILLI_TO_NANO  1000000
 
@@ -761,7 +762,6 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, unsigned int flags,
        snprintf(fn, sizeof(fn), "/dev/audio/pcmC%u", card);
 #endif
 
-
        pcm->flags = flags;
        pcm->fd = open(fn, O_RDWR);
        if (pcm->fd < 0) {
@@ -865,7 +865,36 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, unsigned int flags,
                        goto fail_cleanup_buffers;
                }
        }
-
+       if (pcm->flags & PCM_IN) {
+               struct ap_buffer_s *apb = (struct ap_buffer_s *)pcm->pBuffers[0];
+               if (apb->nmaxbytes - apb->nbytes >= sizeof(struct wav_header_s)) {
+                       struct wav_header_s *wav = (struct wav_header_s *)(&apb->samp[0]);
+                       
+                       /* Transfer the purported WAV file header into our stack storage,
+                        * correcting for endian issues as needed.
+                        */
+                       
+                       wav->hdr.chunkid = pcm_leuint32(WAV_HDR_CHUNKID);       
+                       wav->hdr.chunklen = 0;
+                       wav->hdr.format = pcm_leuint32(WAV_HDR_FORMAT);
+                       
+                       wav->fmt.chunkid = pcm_leuint32(WAV_FMT_CHUNKID);
+                       wav->fmt.chunklen = pcm_leuint32(WAV_FMT_CHUNKLEN);
+                       wav->fmt.format = pcm_leuint16(WAV_FMT_FORMAT);
+                       wav->fmt.nchannels = pcm_leuint16(pcm->config.channels);
+                       wav->fmt.samprate = pcm_leuint32(pcm->config.rate);
+                       wav->fmt.byterate = pcm_leuint32(pcm->config.rate*pcm->config.channels*pcm_format_to_bits(pcm->config.format)/8);
+                       wav->fmt.align = pcm_leuint16(pcm->config.channels*pcm_format_to_bits(pcm->config.format)/8);
+                       wav->fmt.bpsamp = pcm_leuint16(pcm_format_to_bits(pcm->config.format));
+                       
+                       wav->data.chunkid = pcm_leuint32(WAV_DATA_CHUNKID);
+                       wav->data.chunklen = 0;
+                       
+                       apb->nbytes = sizeof(struct wav_header_s);
+               } else {
+                       goto fail_cleanup_buffers;
+               }
+       }
        pcm->underruns = 0;
        return pcm;
 
index 1e2e0e4..027f027 100644 (file)
@@ -157,14 +157,6 @@ static void pcm_dump(FAR const struct wav_header_s *wav);
 #define pcm_dump(w)
 #endif
 
-#ifdef CONFIG_ENDIAN_BIG
-static uint16_t pcm_leuint16(uint16_t value);
-static uint16_t pcm_leuint32(uint32_t value);
-#else
-#define pcm_leuint16(v) (v)
-#define pcm_leuint32(v) (v)
-#endif
-
 static inline bool pcm_validwav(FAR const struct wav_header_s *wav);
 static bool pcm_parsewav(FAR struct pcm_decode_s *priv, uint8_t *data);
 
@@ -308,7 +300,7 @@ static uint16_t pcm_leuint16(uint16_t value)
  ****************************************************************************/
 
 #ifdef CONFIG_ENDIAN_BIG
-static uint16_t pcm_leuint32(uint32_t value)
+static uint32_t pcm_leuint32(uint32_t value)
 {
        return (((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value & 0xff000000) >> 24));
 }
index 42d6948..287f913 100644 (file)
@@ -170,6 +170,15 @@ extern "C" {
  *
  ****************************************************************************/
 
+#ifdef CONFIG_ENDIAN_BIG
+static uint16_t pcm_leuint16(uint16_t value);
+static uint32_t pcm_leuint32(uint32_t value);
+#else
+#define pcm_leuint16(v) (v)
+#define pcm_leuint32(v) (v)
+#endif
+
+
 FAR struct audio_lowerhalf_s *pcm_decode_initialize(FAR struct audio_lowerhalf_s *dev);
 
 #undef EXTERN