From: Shivam Garg Date: Fri, 8 Sep 2017 11:48:34 +0000 (+0900) Subject: WAV header construction in tinyalsa X-Git-Tag: 1.1_Public_Release~188^2~37 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1c0d989aa4cf29e0460ee5bdc9dd5e7794f2f4cf;p=rtos%2Ftinyara.git WAV header construction in tinyalsa 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 --- diff --git a/framework/src/tinyalsa/tinyalsa.c b/framework/src/tinyalsa/tinyalsa.c index 26f6c47..071d258 100644 --- a/framework/src/tinyalsa/tinyalsa.c +++ b/framework/src/tinyalsa/tinyalsa.c @@ -66,6 +66,7 @@ #include #include +#include #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; diff --git a/os/audio/pcm_decode.c b/os/audio/pcm_decode.c index 1e2e0e4..027f027 100644 --- a/os/audio/pcm_decode.c +++ b/os/audio/pcm_decode.c @@ -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)); } diff --git a/os/include/tinyara/audio/pcm.h b/os/include/tinyara/audio/pcm.h index 42d6948..287f913 100644 --- a/os/include/tinyara/audio/pcm.h +++ b/os/include/tinyara/audio/pcm.h @@ -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