summaryrefslogtreecommitdiff
path: root/nuttx/audio
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-05 10:06:05 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-05 10:06:05 -0600
commitc202f971b72b854b58c7a17afaf43f035f9f7460 (patch)
treea29a3596e6c9c82798406a421e6a630aa52b6ce7 /nuttx/audio
parente54ef60df4e062df1f8fc4bd12792ee3f5dad057 (diff)
downloadnuttx-c202f971b72b854b58c7a17afaf43f035f9f7460.tar.gz
nuttx-c202f971b72b854b58c7a17afaf43f035f9f7460.tar.bz2
nuttx-c202f971b72b854b58c7a17afaf43f035f9f7460.zip
PCM decoder: Handle errors in the PCM WAV file in a way that the Nxplayer can recover gracefully: Send and Audio Complete message.
Diffstat (limited to 'nuttx/audio')
-rw-r--r--nuttx/audio/pcm_decode.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/nuttx/audio/pcm_decode.c b/nuttx/audio/pcm_decode.c
index 1caf155d1..b2109923c 100644
--- a/nuttx/audio/pcm_decode.c
+++ b/nuttx/audio/pcm_decode.c
@@ -340,7 +340,9 @@ static inline bool pcm_validwav(FAR const struct wav_header_s *wav)
* Name: pcm_parsewav
*
* Description:
- * Parse and verify the WAV file header.
+ * Parse and verify the WAV file header. A WAV file is a particular
+ * packaging of an audio file; on PCM encoded WAV files are accepted by
+ * this driver.
*
****************************************************************************/
@@ -374,7 +376,7 @@ static bool pcm_parsewav(FAR struct pcm_decode_s *priv, uint8_t *data)
pcm_dump(&localwav);
- /* Check if the file is a valid WAV header */
+ /* Check if the file is a valid PCM WAV header */
ret = pcm_validwav(&localwav);
if (ret)
@@ -1044,8 +1046,8 @@ static int pcm_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,
}
#ifndef CONFIG_AUDIO_EXCLUDE_FFORWARD
- audvdbg("Received: apb=%p curbyte=%d nbytes=%d\n",
- apb, apb->curbyte, apb->nbytes);
+ audvdbg("Received: apb=%p curbyte=%d nbytes=%d flags=%04x\n",
+ apb, apb->curbyte, apb->nbytes, apb->flags);
/* Perform any necessary sub-sampling operations */
@@ -1072,22 +1074,12 @@ static int pcm_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,
if (bytesleft >= sizeof(struct wav_header_s))
{
- /* Parse and verify the candidate WAV file header */
+ /* Parse and verify the candidate PCM WAV file header */
if (pcm_parsewav(priv, &apb->samp[apb->curbyte]))
{
struct audio_caps_s caps;
- /* Now we are streaming. Unless for some reason there is only one
- * audio buffer in the audio stream. In that case, this will be
- * marked as the final buffer
- */
-
- if ((apb->flags & AUDIO_APB_FINAL) == 0)
- {
- priv->streaming = true;
- }
-
/* Configure the lower level for the number of channels, bitrate,
* and sample bitwidth.
*/
@@ -1130,25 +1122,46 @@ static int pcm_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,
audvdbg("Pass to lower enqueuebuffer: apb=%p curbyte=%d nbytes=%d\n",
apb, apb->curbyte, apb->nbytes);
- return lower->ops->enqueuebuffer(lower, apb);
+ ret = lower->ops->enqueuebuffer(lower, apb);
+ if (ret == OK)
+ {
+ /* Now we are streaming. Unless for some reason there is only
+ * one audio buffer in the audio stream. In that case, this
+ * will be marked as the final buffer
+ */
+
+ priv->streaming = ((apb->flags & AUDIO_APB_FINAL) == 0);
+ return OK;
+ }
}
- /* Return the unhandled buffer to the previous level with an error
- * indication.
+ auddbg("ERROR: Invalid PCM WAV file\n");
+
+ /* The normal protocol for streaming errors is as follows:
+ *
+ * (1) Fail the enqueueing by returned a negated error value. The
+ * upper level then knows that this buffer was not queue.
+ * (2) Return all queued buffers to the caller using the
+ * AUDIO_CALLBACK_DEQUEUE callback
+ * (3) Terminate playing using the AUDIO_CALLBACK_COMPLETE
+ * callback.
+ *
+ * In this case we fail on the very first buffer and we need only
+ * do (1) and (3).
*/
#ifdef CONFIG_AUDIO_MULTI_SESSION
- priv->export.upper(priv->export.priv, AUDIO_CALLBACK_DEQUEUE, apb,
- -EINVAL, NULL);
+ priv->export.upper(priv->export.priv, AUDIO_CALLBACK_COMPLETE,
+ NULL, OK, NULL);
#else
- priv->export.upper(priv->export.priv, AUDIO_CALLBACK_DEQUEUE, apb,
- -EINVAL);
+ priv->export.upper(priv->export.priv, AUDIO_CALLBACK_COMPLETE,
+ NULL, OK);
#endif
}
/* This is not a WAV file! */
- auddbg("ERROR: Invalid WAV file\n");
+ auddbg("ERROR: Invalid PCM WAV file\n");
return -EINVAL;
}