This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 904f391982c48e4de26a2f2f34baceb45b17e275 Author: yangyalei <[email protected]> AuthorDate: Mon Jul 21 19:55:24 2025 +0800 nuttx/audio: Add audio_try_enqueue support upper driver check whether enqueue apb buffer to the lower driver Signed-off-by: yangyalei <[email protected]> --- audio/audio.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 861da7e94df..ba31a29f5c0 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -26,6 +26,7 @@ #include <nuttx/config.h> +#include <sys/param.h> #include <sys/types.h> #include <sys/stat.h> #include <stdint.h> @@ -66,6 +67,8 @@ # define CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO 1 #endif +#define AUDIO_ENQUEUE_THRESHOLD 2 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -375,6 +378,66 @@ static inline int audio_getnstate(FAR struct audio_upperhalf_s *upper, return nstate; } +/**************************************************************************** + * Name: audio_try_enqueue + * + * Description: + * Try enqueue audio buffer + * + ****************************************************************************/ + +static int audio_try_enqueue(FAR struct audio_upperhalf_s *upper) +{ + FAR struct audio_lowerhalf_s *lower = upper->dev; + FAR struct audio_openpriv_s *priv; + int ret = OK; + + for (; ; ) + { + uint32_t count = upper->status->head - upper->status->tail; + bool ready = false; + bool wait = false; + + for (priv = upper->head; priv != NULL; priv = priv->flink) + { + if (priv->state == AUDIO_STATE_OPEN || + priv->state == AUDIO_STATE_PAUSED) + { + continue; + } + else if (priv->head > upper->status->head) + { + ready = true; + } + else if (priv->head < upper->status->head || + priv->head <= upper->status->tail) + { + priv->state = AUDIO_STATE_XRUN; + } + else + { + wait = true; + } + } + + if (!ready || (wait && count > AUDIO_ENQUEUE_THRESHOLD)) + { + return OK; + } + + ret = lower->ops->enqueuebuffer( + lower, upper->apbs[upper->status->head % upper->periods]); + if (ret < 0) + { + return ret; + } + + upper->status->head++; + } + + return ret; +} + /**************************************************************************** * Name: audio_configure * @@ -756,7 +819,7 @@ static int audio_enqueuebuffer(FAR struct file *filep, FAR struct audio_lowerhalf_s *lower = upper->dev; FAR struct audio_openpriv_s *priv = filep->f_priv; irqstate_t flags; - int ret; + int ret = OK; DEBUGASSERT(lower->ops->enqueuebuffer != NULL); @@ -774,12 +837,16 @@ static int audio_enqueuebuffer(FAR struct file *filep, } else { - flags = spin_lock_irqsave(&upper->spinlock); - priv->head += bufdesc->numbytes; - spin_unlock_irqrestore(&upper->spinlock, flags); + flags = spin_lock_irqsave_nopreempt(&upper->spinlock); + upper->apbs[priv->head % upper->periods]->nbytes = + MAX(upper->apbs[priv->head % upper->periods]->nbytes, + bufdesc->numbytes); + priv->head++; + ret = audio_try_enqueue(upper); + spin_unlock_irqrestore_nopreempt(&upper->spinlock, flags); } - return OK; + return ret; } /**************************************************************************** @@ -1319,6 +1386,7 @@ static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper, flags = spin_lock_irqsave_nopreempt(&upper->spinlock); upper->status->tail++; + audio_try_enqueue(upper); for (priv = upper->head; priv != NULL; priv = priv->flink) { if (priv->fd > 0)
