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 d15f69cdb6180aed10b1757a8e39e01bae68de10
Author: yangyalei <[email protected]>
AuthorDate: Wed Aug 6 16:39:48 2025 +0800

    nuttx/audio: Add audio_stop/pause/resume
    
    relayout the code for easy modification
    
    Signed-off-by: yangyalei <[email protected]>
---
 audio/audio.c | 383 +++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 230 insertions(+), 153 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index d9153693f21..3d88ec33d43 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -105,20 +105,13 @@ static int      audio_mmap(FAR struct file *filep,
                            FAR struct mm_map_entry_s *map);
 static int      audio_poll(FAR struct file *filep,
                            FAR struct pollfd *fds, bool setup);
-static int      audio_allocbuffer(FAR struct audio_upperhalf_s *upper,
-                                  FAR struct audio_buf_desc_s * bufdesc);
-static int      audio_freebuffer(FAR struct audio_upperhalf_s *upper,
-                                 FAR struct audio_buf_desc_s * bufdesc);
 #ifdef CONFIG_AUDIO_MULTI_SESSION
-static int      audio_start(FAR struct audio_upperhalf_s *upper,
-                            FAR void *session);
 static void     audio_callback(FAR void *priv,
                                uint16_t reason,
                                FAR struct ap_buffer_s *apb,
                                uint16_t status,
                                FAR void *session);
 #else
-static int      audio_start(FAR struct audio_upperhalf_s *upper);
 static void     audio_callback(FAR void *priv,
                                uint16_t reason,
                                FAR struct ap_buffer_s *apb,
@@ -376,6 +369,84 @@ static int audio_configure(FAR struct audio_upperhalf_s 
*upper,
   return ret;
 }
 
+/****************************************************************************
+ * Name: audio_pause
+ *
+ * Description:
+ *   Handle the AUDIOIOC_PAUSE ioctl command
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+static int audio_pause(FAR struct file *filep, FAR void *session)
+#else
+static int audio_pause(FAR struct file *filep)
+#endif
+{
+  FAR struct inode *inode = filep->f_inode;
+  FAR struct audio_upperhalf_s *upper = inode->i_private;
+  FAR struct audio_lowerhalf_s *lower = upper->dev;
+  int ret = OK;
+
+  DEBUGASSERT(upper != NULL && lower->ops->pause != NULL);
+
+  if (upper->status->state == AUDIO_STATE_RUNNING)
+    {
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+      ret = lower->ops->pause(lower, session);
+#else
+      ret = lower->ops->pause(lower);
+#endif
+      if (ret == OK)
+        {
+          audio_setstate(upper, AUDIO_STATE_PAUSED);
+        }
+    }
+
+  return ret;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME */
+
+/****************************************************************************
+ * Name: audio_resume
+ *
+ * Description:
+ *   Handle the AUDIOIOC_resume ioctl command
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+static int audio_resume(FAR struct file *filep, FAR void *session)
+#else
+static int audio_resume(FAR struct file *filep)
+#endif
+{
+  FAR struct inode *inode = filep->f_inode;
+  FAR struct audio_upperhalf_s *upper = inode->i_private;
+  FAR struct audio_lowerhalf_s *lower = upper->dev;
+  int ret = OK;
+
+  DEBUGASSERT(upper != NULL && lower->ops->resume != NULL);
+
+  if (upper->status->state == AUDIO_STATE_PAUSED)
+    {
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+      ret = lower->ops->resume(lower, session);
+#else
+      ret = lower->ops->resume(lower);
+#endif
+      if (ret == OK)
+        {
+          audio_setstate(upper, AUDIO_STATE_RUNNING);
+        }
+    }
+
+  return ret;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME */
+
 /****************************************************************************
  * Name: audio_start
  *
@@ -385,12 +456,13 @@ static int audio_configure(FAR struct audio_upperhalf_s 
*upper,
  ****************************************************************************/
 
 #ifdef CONFIG_AUDIO_MULTI_SESSION
-static int audio_start(FAR struct audio_upperhalf_s *upper,
-                       FAR void *session)
+static int audio_start(FAR struct file *filep, FAR void *session)
 #else
-static int audio_start(FAR struct audio_upperhalf_s *upper)
+static int audio_start(FAR struct file *filep)
 #endif
 {
+  FAR struct inode *inode = filep->f_inode;
+  FAR struct audio_upperhalf_s *upper = inode->i_private;
   FAR struct audio_lowerhalf_s *lower = upper->dev;
   int ret = OK;
 
@@ -423,6 +495,146 @@ static int audio_start(FAR struct audio_upperhalf_s 
*upper)
   return ret;
 }
 
+/****************************************************************************
+ * Name: audio_stop
+ *
+ * Description:
+ *   Handle the AUDIOIOC_STOP ioctl command
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+static int audio_stop(FAR struct file *filep, FAR void *session)
+#else
+static int audio_stop(FAR struct file *filep)
+#endif
+{
+  FAR struct inode *inode = filep->f_inode;
+  FAR struct audio_upperhalf_s *upper = inode->i_private;
+  FAR struct audio_lowerhalf_s *lower = upper->dev;
+  int ret = OK;
+
+  DEBUGASSERT(upper != NULL && lower->ops->stop != NULL);
+
+  if (upper->status->state == AUDIO_STATE_RUNNING ||
+      upper->status->state == AUDIO_STATE_PAUSED)
+    {
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+      ret = lower->ops->stop(lower, session);
+#else
+      ret = lower->ops->stop(lower);
+#endif
+      if (ret == OK)
+        {
+          audio_setstate(upper, AUDIO_STATE_DRAINING);
+        }
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: audio_freebuffer
+ *
+ * Description:
+ *   Handle the AUDIOIOC_FREEBUFFER ioctl command
+ *
+ ****************************************************************************/
+
+static int audio_freebuffer(FAR struct audio_upperhalf_s *upper,
+                            FAR struct audio_buf_desc_s *bufdesc)
+{
+  FAR struct audio_lowerhalf_s *lower = upper->dev;
+  bool share = false;
+  int ret;
+
+  if (bufdesc->u.buffer == NULL)
+    {
+      bufdesc->u.buffer = upper->apbs[upper->periods - 1];
+      share = true;
+    }
+
+  if (lower->ops->freebuffer)
+    {
+      ret = lower->ops->freebuffer(lower, bufdesc);
+    }
+  else
+    {
+      /* Perform a simple apb_free operation */
+
+      DEBUGASSERT(bufdesc->u.buffer != NULL);
+      apb_free(bufdesc->u.buffer);
+      ret = sizeof(struct audio_buf_desc_s);
+    }
+
+  if (ret > 0 && share)
+    {
+      bufdesc->u.buffer = NULL;
+      upper->periods--;
+      upper->apbs[upper->periods] = NULL;
+      if (upper->periods == 0)
+        {
+          kmm_free(upper->apbs);
+          upper->apbs = NULL;
+        }
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: audio_allocbuffer
+ *
+ * Description:
+ *   Handle the AUDIOIOC_ALLOCBUFFER ioctl command
+ *
+ ****************************************************************************/
+
+static int audio_allocbuffer(FAR struct audio_upperhalf_s *upper,
+                             FAR struct audio_buf_desc_s *bufdesc)
+{
+  FAR struct audio_lowerhalf_s *lower = upper->dev;
+  FAR struct ap_buffer_s *apb;
+  bool share = false;
+  FAR void *newaddr;
+  int ret;
+
+  if (bufdesc->u.pbuffer == NULL)
+    {
+      bufdesc->u.pbuffer = &apb;
+      share = true;
+    }
+
+  if (lower->ops->allocbuffer != NULL)
+    {
+      ret = lower->ops->allocbuffer(lower, bufdesc);
+    }
+  else
+    {
+      /* Perform a simple kumm_malloc operation assuming 1 session */
+
+      ret = apb_alloc(bufdesc);
+    }
+
+  if (ret > 0 && share)
+    {
+      newaddr = kmm_realloc(upper->apbs,
+                            (upper->periods + 1) * sizeof(*upper->apbs));
+      if (newaddr == NULL)
+        {
+          audio_freebuffer(upper, bufdesc);
+          return -ENOMEM;
+        }
+
+      upper->apbs = (FAR struct ap_buffer_s **)newaddr;
+      upper->apbs[upper->periods] = apb;
+      upper->periods++;
+      bufdesc->u.pbuffer = NULL;
+    }
+
+  return ret;
+}
+
 /****************************************************************************
  * Name: audio_ioctl
  *
@@ -437,9 +649,6 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
   FAR struct audio_upperhalf_s *upper = inode->i_private;
   FAR struct audio_lowerhalf_s *lower = upper->dev;
   FAR struct audio_buf_desc_s  *bufdesc;
-#ifdef CONFIG_AUDIO_MULTI_SESSION
-  FAR void *session;
-#endif
   irqstate_t flags;
   int ret;
 
@@ -511,15 +720,13 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
       case AUDIOIOC_START:
         {
           audinfo("AUDIOIOC_START\n");
-          DEBUGASSERT(lower->ops->start != NULL);
 
           /* Start the audio stream */
 
 #ifdef CONFIG_AUDIO_MULTI_SESSION
-          session = (FAR void *) arg;
-          ret = audio_start(upper, session);
+          ret = audio_start(filep, (FAR void *)arg);
 #else
-          ret = audio_start(upper);
+          ret = audio_start(filep);
 #endif
         }
         break;
@@ -533,22 +740,12 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
       case AUDIOIOC_STOP:
         {
           audinfo("AUDIOIOC_STOP\n");
-          DEBUGASSERT(lower->ops->stop != NULL);
 
-          if (upper->status->state == AUDIO_STATE_RUNNING ||
-              upper->status->state == AUDIO_STATE_PAUSED)
-            {
 #ifdef CONFIG_AUDIO_MULTI_SESSION
-              session = (FAR void *) arg;
-              ret = lower->ops->stop(lower, session);
+          ret = audio_stop(filep, (FAR void *)arg);
 #else
-              ret = lower->ops->stop(lower);
+          ret = audio_stop(filep);
 #endif
-              if (ret == OK)
-                {
-                  audio_setstate(upper, AUDIO_STATE_DRAINING);
-                }
-            }
         }
         break;
 #endif /* CONFIG_AUDIO_EXCLUDE_STOP */
@@ -563,21 +760,12 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
       case AUDIOIOC_PAUSE:
         {
           audinfo("AUDIOIOC_PAUSE\n");
-          DEBUGASSERT(lower->ops->pause != NULL);
 
-          if (upper->status->state == AUDIO_STATE_RUNNING)
-            {
 #ifdef CONFIG_AUDIO_MULTI_SESSION
-              session = (FAR void *) arg;
-              ret = lower->ops->pause(lower, session);
+          ret = audio_pause(filep, (FAR void *)arg);
 #else
-              ret = lower->ops->pause(lower);
+          ret = audio_pause(filep);
 #endif
-              if (ret == OK)
-                {
-                  audio_setstate(upper, AUDIO_STATE_PAUSED);
-                }
-            }
         }
         break;
 
@@ -589,21 +777,12 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
       case AUDIOIOC_RESUME:
         {
           audinfo("AUDIOIOC_RESUME\n");
-          DEBUGASSERT(lower->ops->resume != NULL);
 
-          if (upper->status->state == AUDIO_STATE_PAUSED)
-            {
 #ifdef CONFIG_AUDIO_MULTI_SESSION
-              session = (FAR void *) arg;
-              ret = lower->ops->resume(lower, session);
+          ret = audio_resume(filep, (FAR void *)arg);
 #else
-              ret = lower->ops->resume(lower);
+          ret = audio_resume(filep);
 #endif
-              if (ret == OK)
-                {
-                  audio_setstate(upper, AUDIO_STATE_RUNNING);
-                }
-            }
         }
         break;
 
@@ -879,108 +1058,6 @@ static int audio_poll(FAR struct file *filep,
   return OK;
 }
 
-/****************************************************************************
- * Name: audio_allocbuffer
- *
- * Description:
- *   Handle the AUDIOIOC_ALLOCBUFFER ioctl command
- *
- ****************************************************************************/
-
-static int audio_allocbuffer(FAR struct audio_upperhalf_s *upper,
-                             FAR struct audio_buf_desc_s *bufdesc)
-{
-  FAR struct audio_lowerhalf_s *lower = upper->dev;
-  FAR struct ap_buffer_s *apb;
-  bool share = false;
-  FAR void *newaddr;
-  int ret;
-
-  if (bufdesc->u.pbuffer == NULL)
-    {
-      bufdesc->u.pbuffer = &apb;
-      share = true;
-    }
-
-  if (lower->ops->allocbuffer)
-    {
-      ret = lower->ops->allocbuffer(lower, bufdesc);
-    }
-  else
-    {
-      /* Perform a simple kumm_malloc operation assuming 1 session */
-
-      ret = apb_alloc(bufdesc);
-    }
-
-  if (ret > 0 && share)
-    {
-      newaddr = kmm_realloc(upper->apbs,
-                            (upper->periods + 1) * sizeof(*upper->apbs));
-      if (newaddr == NULL)
-        {
-          audio_freebuffer(upper, bufdesc);
-          return -ENOMEM;
-        }
-
-      upper->apbs = (FAR struct ap_buffer_s **)newaddr;
-      upper->apbs[upper->periods] = apb;
-      upper->periods++;
-      bufdesc->u.pbuffer = NULL;
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: audio_freebuffer
- *
- * Description:
- *   Handle the AUDIOIOC_FREEBUFFER ioctl command
- *
- ****************************************************************************/
-
-static int audio_freebuffer(FAR struct audio_upperhalf_s *upper,
-                            FAR struct audio_buf_desc_s *bufdesc)
-{
-  FAR struct audio_lowerhalf_s *lower = upper->dev;
-  bool share = false;
-  int ret;
-
-  if (bufdesc->u.buffer == NULL)
-    {
-      bufdesc->u.buffer = upper->apbs[upper->periods - 1];
-      share = true;
-    }
-
-  if (lower->ops->freebuffer)
-    {
-      ret = lower->ops->freebuffer(lower, bufdesc);
-    }
-  else
-    {
-      /* Perform a simple apb_free operation */
-
-      DEBUGASSERT(bufdesc->u.buffer != NULL);
-      apb_free(bufdesc->u.buffer);
-      ret = sizeof(struct audio_buf_desc_s);
-    }
-
-  if (ret > 0 && share)
-    {
-      bufdesc->u.buffer = NULL;
-      upper->apbs[upper->periods] = NULL;
-      upper->periods--;
-      if (upper->periods == 0)
-        {
-          kmm_free(upper->apbs);
-          upper->apbs = NULL;
-        }
-    }
-
-  return ret;
-}
-
 /****************************************************************************
  * Name: audio_dequeuebuffer
  *

Reply via email to