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 2cc624a4c4332aeadb59491f5e07a95944cbf74d
Author: yangyalei <[email protected]>
AuthorDate: Fri May 30 11:12:21 2025 +0800

    nuttx/audio: add AUDIOIOC_GETSTATE ioctl
    
    support get lower driver state
    
    Signed-off-by: yangyalei <[email protected]>
---
 audio/audio.c               | 40 +++++++++++++++++++++++++++++++++-------
 include/nuttx/audio/audio.h | 10 ++++++++++
 2 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 62ab35090b9..232ea5311b3 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -74,7 +74,7 @@
 struct audio_upperhalf_s
 {
   uint8_t                      crefs;   /* The number of times the device has 
been opened */
-  volatile bool                started; /* True: playback is active */
+  volatile enum audio_state_e  state;   /* lowerhalf state */
   struct audio_info_s          info;    /* Record the last playing audio 
format */
   mutex_t                      lock;    /* Supports mutual exclusion */
   FAR struct audio_lowerhalf_s *dev;    /* lower-half state */
@@ -228,6 +228,7 @@ static int audio_close(FAR struct file *filep)
 
       lower->ops->shutdown(lower);
       upper->usermq = NULL;
+      upper->state = AUDIO_STATE_OPEN;
     }
 
   ret = OK;
@@ -319,6 +320,7 @@ static int audio_configure(FAR struct audio_upperhalf_s 
*upper,
   if (ret == OK && (caps->ac_type == AUDIO_TYPE_INPUT ||
                     caps->ac_type == AUDIO_TYPE_OUTPUT))
     {
+      upper->state = AUDIO_STATE_PREPARED;
       upper->info.format = caps->ac_subtype;
       upper->info.channels = caps->ac_channels;
       upper->info.subformat = caps->ac_controls.b[2];
@@ -351,7 +353,7 @@ static int audio_start(FAR struct audio_upperhalf_s *upper)
 
   /* Verify that the Audio is not already running */
 
-  if (!upper->started)
+  if (upper->state == AUDIO_STATE_PREPARED)
     {
       /* Invoke the bottom half method to start the audio stream */
 
@@ -369,7 +371,7 @@ static int audio_start(FAR struct audio_upperhalf_s *upper)
         {
           /* Indicate that the audio stream has started */
 
-          upper->started = true;
+          upper->state = AUDIO_STATE_RUNNING;
         }
     }
 
@@ -487,7 +489,8 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
           audinfo("AUDIOIOC_STOP\n");
           DEBUGASSERT(lower->ops->stop != NULL);
 
-          if (upper->started)
+          if (upper->state == AUDIO_STATE_RUNNING ||
+              upper->state == AUDIO_STATE_PAUSED)
             {
 #ifdef CONFIG_AUDIO_MULTI_SESSION
               session = (FAR void *) arg;
@@ -495,7 +498,10 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
 #else
               ret = lower->ops->stop(lower);
 #endif
-              upper->started = false;
+              if (ret == OK)
+                {
+                  upper->state = AUDIO_STATE_DRAINING;
+                }
             }
         }
         break;
@@ -513,7 +519,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
           audinfo("AUDIOIOC_PAUSE\n");
           DEBUGASSERT(lower->ops->pause != NULL);
 
-          if (upper->started)
+          if (upper->state == AUDIO_STATE_RUNNING)
             {
 #ifdef CONFIG_AUDIO_MULTI_SESSION
               session = (FAR void *) arg;
@@ -521,6 +527,10 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
 #else
               ret = lower->ops->pause(lower);
 #endif
+              if (ret == OK)
+                {
+                  upper->state = AUDIO_STATE_PAUSED;
+                }
             }
         }
         break;
@@ -535,7 +545,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
           audinfo("AUDIOIOC_RESUME\n");
           DEBUGASSERT(lower->ops->resume != NULL);
 
-          if (upper->started)
+          if (upper->state == AUDIO_STATE_PAUSED)
             {
 #ifdef CONFIG_AUDIO_MULTI_SESSION
               session = (FAR void *) arg;
@@ -543,6 +553,10 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
 #else
               ret = lower->ops->resume(lower);
 #endif
+              if (ret == OK)
+                {
+                  upper->state = AUDIO_STATE_RUNNING;
+                }
             }
         }
         break;
@@ -693,6 +707,18 @@ static int audio_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
         }
         break;
 
+      /* AUDIOIOC_GETSTATE - Get lower driver state
+       *
+       *   ioctl argument - pointer to receive the state
+       */
+
+      case AUDIOIOC_GETSTATE:
+        {
+          *(FAR enum audio_state_e *)arg = upper->state;
+          ret = OK;
+        }
+        break;
+
       /* Any unrecognized IOCTL commands might be
        * platform-specific ioctl commands
        */
diff --git a/include/nuttx/audio/audio.h b/include/nuttx/audio/audio.h
index d6b88af18d6..29e4d789a61 100644
--- a/include/nuttx/audio/audio.h
+++ b/include/nuttx/audio/audio.h
@@ -118,6 +118,7 @@
 #define AUDIOIOC_FLUSH              _AUDIOIOC(20)
 #define AUDIOIOC_GETPOSITION        _AUDIOIOC(21)
 #define AUDIOIOC_GETAUDIOINFO       _AUDIOIOC(22)
+#define AUDIOIOC_GETSTATE           _AUDIOIOC(23)
 
 /* Audio Device Types *******************************************************/
 
@@ -376,6 +377,15 @@
 
 #define AUDIO_CHANNELS_RANGE(min, max) ((uint8_t)(((min) << 4) | ((max) & 
0xf)))
 
+/* State of appl and lower driver, higher value = higher priority */
+
+#define AUDIO_STATE_OPEN           0
+#define AUDIO_STATE_PREPARED       1
+#define AUDIO_STATE_PAUSED         2
+#define AUDIO_STATE_XRUN           3
+#define AUDIO_STATE_DRAINING       4
+#define AUDIO_STATE_RUNNING        5
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/

Reply via email to