Bläddra i källkod

[RFC][doxygen]Doxygen comment standard processing (#10058)

Signed-off-by: 1078249029 <1078249029@qq.com>
wumingzi 2 månader sedan
förälder
incheckning
fb64052722

+ 2 - 0
.github/workflows/doxygen.yml

@@ -10,6 +10,7 @@ on:
       - 'components/finsh/**'
       - 'components/drivers/include/drivers/**'
       - 'components/drivers/clk/**'
+      - 'components/drivers/audio/**'
       - 'components/dfs/dfs_v2/src/**'
       - 'components/dfs/dfs_v2/include/**'
       - '.github/workflows/doxygen.yml'
@@ -23,6 +24,7 @@ on:
       - 'components/finsh/**'
       - 'components/drivers/include/drivers/**'
       - 'components/drivers/clk/**'
+      - 'components/drivers/audio/**'
       - 'components/dfs/dfs_v2/src/**'
       - 'components/dfs/dfs_v2/include/**'
       - '.github/workflows/doxygen.yml'

+ 172 - 1
components/drivers/audio/dev_audio.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2023, RT-Thread Development Team
+ * Copyright (c) 2006-2025 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -22,6 +22,12 @@
 #define MIN(a, b)         ((a) < (b) ? (a) : (b))
 #endif
 
+/**
+ * @addtogroup group_AudioPipe
+ */
+
+/** @{ */
+
 enum
 {
     REPLAY_EVT_NONE  = 0x00,
@@ -29,6 +35,20 @@ enum
     REPLAY_EVT_STOP  = 0x02,
 };
 
+/**
+ * @brief Send a replay frame to the audio hardware device
+ *
+ * This function handles sending audio data from the memory queue to the hardware buffer for playback.
+ * If there is no data available in the queue, it sends zero frames. Otherwise, it copies data from the memory pool
+ * to the hardware device FIFO and manages the read index and position accordingly.
+ *
+ * @param[in] audio pointer to the audio device structure
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ *
+ * @note This function may temporarily disable interrupts or perform time-consuming operations like memcpy,
+ *       which could affect system responsiveness
+ */
 static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
 {
     rt_err_t result = RT_EOK;
@@ -108,6 +128,13 @@ static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
     return result;
 }
 
+/**
+ * @brief Write replay frame into audio device replay queue
+ *
+ * @param[in] audio pointer to audio device
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio)
 {
     rt_err_t result = RT_EOK;
@@ -125,6 +152,13 @@ static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio)
     return result;
 }
 
+/**
+ * @brief Replay audio
+ *
+ * @param[in] audio pointer to audio device
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _aduio_replay_start(struct rt_audio_device *audio)
 {
     rt_err_t result = RT_EOK;
@@ -142,6 +176,16 @@ static rt_err_t _aduio_replay_start(struct rt_audio_device *audio)
     return result;
 }
 
+/**
+ * @brief Stop replaying audio
+ *
+ * When audio->replay->queue is empty and the audio->replay->event was set REPLAY_EVT_STOP,
+ * _audio_send_replay_frame will send completion to stop replaying audio.
+ *
+ * @param[in] audio pointer to audio device
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _aduio_replay_stop(struct rt_audio_device *audio)
 {
     rt_err_t result = RT_EOK;
@@ -170,6 +214,13 @@ static rt_err_t _aduio_replay_stop(struct rt_audio_device *audio)
     return result;
 }
 
+/**
+ * @brief Open audio pipe and start to record audio
+ *
+ * @param[in] audio pointer to audio device
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _audio_record_start(struct rt_audio_device *audio)
 {
     rt_err_t result = RT_EOK;
@@ -190,6 +241,13 @@ static rt_err_t _audio_record_start(struct rt_audio_device *audio)
     return result;
 }
 
+/**
+ * @brief stop recording audio and closeaudio pipe
+ *
+ * @param[in] audio pointer to audio device
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _audio_record_stop(struct rt_audio_device *audio)
 {
     rt_err_t result = RT_EOK;
@@ -210,6 +268,20 @@ static rt_err_t _audio_record_stop(struct rt_audio_device *audio)
     return result;
 }
 
+/**
+ * @brief Init audio pipe
+ *
+ * In kernel, this function will set replay or record function depending on device
+ * flag. For replaying, it will malloc for managing audio replay struct meanwhile
+ * creating mempool and dataqueue.For recording, it will creat audio pipe and
+ * it's ringbuffer.
+ * In driver, this function will only execute hardware driver initialization code
+ * and get hardware buffer infomation.
+ *
+ * @param[in] dev pointer to audio device
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _audio_dev_init(struct rt_device *dev)
 {
     rt_err_t result = RT_EOK;
@@ -288,6 +360,15 @@ static rt_err_t _audio_dev_init(struct rt_device *dev)
     return result;
 }
 
+/**
+ * @brief Start record audio
+ *
+ * @param[in] dev pointer to audio device
+ *
+ * @param[in] oflag device flag
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag)
 {
     struct rt_audio_device *audio;
@@ -334,6 +415,13 @@ static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag)
     return RT_EOK;
 }
 
+/**
+ * @brief Stop record, replay or both.
+ *
+ * @param[in] dev pointer to audio device
+ *
+ * @return useless param
+ */
 static rt_err_t _audio_dev_close(struct rt_device *dev)
 {
     struct rt_audio_device *audio;
@@ -357,6 +445,21 @@ static rt_err_t _audio_dev_close(struct rt_device *dev)
     return RT_EOK;
 }
 
+/**
+ * @brief Read audio device
+ *
+ * @param[in] dev pointer to device
+ *
+ * @param[in] pos position when reading
+ *
+ * @param[out] buffer a data buffer to save the read data
+ *
+ * @param[in] size buffer size
+ *
+ * @return the actually read size on successfully, otherwise 0 will be returned.
+ *
+ * @note
+ */
 static rt_ssize_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
 {
     struct rt_audio_device *audio;
@@ -369,6 +472,21 @@ static rt_ssize_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buf
     return rt_device_read(RT_DEVICE(&audio->record->pipe), pos, buffer, size);
 }
 
+/**
+ * @brief Write data into replay data queue and replay it
+ *
+ * @param[in] dev pointer to device
+ *
+ * @param[in] pos useless param
+ *
+ * @param[in] buffer a data buffer to be written into data queue
+ *
+ * @param[in] size buffer size
+ *
+ * @return the actually read size on successfully, otherwise 0 will be returned.
+ *
+ * @note This function will take mutex.
+ */
 static rt_ssize_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size)
 {
 
@@ -424,6 +542,17 @@ static rt_ssize_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const vo
     return index;
 }
 
+/**
+ * @brief Control audio device
+ *
+ * @param[in] dev pointer to device
+ *
+ * @param[in] cmd audio cmd, it can be one of value in @ref audio_control
+ *
+ * @param[in] args command argument
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args)
 {
     rt_err_t result = RT_EOK;
@@ -513,6 +642,19 @@ const static struct rt_device_ops audio_ops =
 };
 #endif
 
+/**
+ * @brief Register and initialize audio device
+ *
+ * @param[in] audio pointer to audio deive
+ *
+ * @param[in] name device name
+ *
+ * @param[in] flag device flags
+ *
+ * @param[in] data user data
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data)
 {
     rt_err_t result = RT_EOK;
@@ -547,6 +689,13 @@ rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_u
     return result;
 }
 
+/**
+ * @brief Set audio sample rate
+ *
+ * @param[in] bitValue audio sample rate, it can be one of value in @ref audio_samp_rates
+ *
+ * @return speed has been set
+ */
 int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
 {
     int speed = 0;
@@ -595,12 +744,32 @@ int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
     return speed;
 }
 
+/**
+ * @brief Send a replay frame to the audio hardware device
+ *
+ * See _audio_send_replay_frame for details
+ *
+ * @param[in] audio pointer to audio device
+ *
+ * @return void
+ */
 void rt_audio_tx_complete(struct rt_audio_device *audio)
 {
     /* try to send next frame */
     _audio_send_replay_frame(audio);
 }
 
+/**
+ * @brief Receive recording from audio device
+ *
+ * @param[in] audio pointer to audio device
+ *
+ * @param[in] pbuf pointer ro data to be received
+ *
+ * @param[in] len buffer size
+ *
+ * @return void
+ */
 void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len)
 {
     /* save data to record pipe */
@@ -610,3 +779,5 @@ void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t
     if (audio->parent.rx_indicate != RT_NULL)
         audio->parent.rx_indicate(&audio->parent, len);
 }
+
+/** @} group_Audio */

+ 76 - 3
components/drivers/audio/dev_audio_pipe.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2023, RT-Thread Development Team
+ * Copyright (c) 2006-2025 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -30,6 +30,22 @@ static void _rt_audio_pipe_resume_writer(struct rt_audio_pipe *pipe)
     }
 }
 
+/**
+ * @brief Read audio pipe
+ *
+ * @param[in] dev pointer to audio device will be read
+ *
+ * @param[in] pos useless param
+ *
+ * @param[in] buffer pointer to ringbuffer of audio pipe to be read
+ *
+ * @param[in] size number of bytes will be read
+ *
+ * @return number of read bytes
+ *
+ * @note This function will execute time-consuming or affecting the
+ *       system operations like memcpy and disable interrupt.
+ */
 static rt_ssize_t rt_audio_pipe_read(rt_device_t dev,
                               rt_off_t    pos,
                               void       *buffer,
@@ -88,6 +104,11 @@ static rt_ssize_t rt_audio_pipe_read(rt_device_t dev,
     return read_nbytes;
 }
 
+/**
+ * @brief Resume audio pipe reader thread
+ *
+ * @param[in] pipe pointer to suspended audio pipe thread
+ */
 static void _rt_audio_pipe_resume_reader(struct rt_audio_pipe *pipe)
 {
     if (pipe->parent.rx_indicate)
@@ -110,6 +131,21 @@ static void _rt_audio_pipe_resume_reader(struct rt_audio_pipe *pipe)
     }
 }
 
+/**
+ * @brief Write data into audio pipe
+ *
+ * @param[in] dev pointer to audio pipe that has been configured
+ *
+ * @param[in] pos useless param
+ *
+ * @param[in] buffer pointer to buffer of ringbuffer
+ *
+ * @param[in] size size of data will be written
+ *
+ * @return number of written bytes
+ *
+ * @note The function will disable interrupt and may suspend current thread
+ */
 static rt_ssize_t rt_audio_pipe_write(rt_device_t dev,
                                rt_off_t    pos,
                                const void *buffer,
@@ -174,6 +210,17 @@ static rt_ssize_t rt_audio_pipe_write(rt_device_t dev,
     return write_nbytes;
 }
 
+/**
+ * @brief Control audio pipe
+ *
+ * @param[in] dev pointer to pipe
+ *
+ * @param[in] cmd control command
+ *
+ * @param[in] args control argument
+ *
+ * @return error code, RT_EOK is successful otherwise means failure
+ */
 static rt_err_t rt_audio_pipe_control(rt_device_t dev, int cmd, void *args)
 {
     struct rt_audio_pipe *pipe;
@@ -198,13 +245,19 @@ const static struct rt_device_ops audio_pipe_ops =
 #endif
 
 /**
+ * @brief Init audio pipe
+ *
  * This function will initialize a pipe device and put it under control of
  * resource management.
  *
  * @param pipe the pipe device
+ *
  * @param name the name of pipe device
+ *
  * @param flag the attribute of the pipe device
+ *
  * @param buf  the buffer of pipe device
+ *
  * @param size the size of pipe device buffer
  *
  * @return the operation status, RT_EOK on successful
@@ -244,7 +297,7 @@ rt_err_t rt_audio_pipe_init(struct rt_audio_pipe *pipe,
 }
 
 /**
- * This function will detach a pipe device from resource management
+ * @brief This function will detach a pipe device from resource management
  *
  * @param pipe the pipe device
  *
@@ -255,6 +308,19 @@ rt_err_t rt_audio_pipe_detach(struct rt_audio_pipe *pipe)
     return rt_device_unregister(&pipe->parent);
 }
 
+/**
+ * @brief Creat audio pipe
+ *
+ * @param[in] name pipe name
+ *
+ * @param[in] flag pipe flags, it can be one of enum rt_audio_pipe_flag items
+ *
+ * @param[in] size ringbuffer size
+ *
+ * @return error code, RT_EOK on initialization successfully
+ *
+ * @note depend on RT_USING_HEAP
+ */
 #ifdef RT_USING_HEAP
 rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size)
 {
@@ -278,6 +344,13 @@ rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size)
     return rt_audio_pipe_init(pipe, name, flag, rb_memptr, size);
 }
 
+/**
+ * @brief Detachaudio pipe and free its ringbuffer
+ *
+ * @param[in] pipe pointer to the pipe will be destory
+ *
+ * @note depend on RT_USING_HEAP
+ */
 void rt_audio_pipe_destroy(struct rt_audio_pipe *pipe)
 {
     if (pipe == RT_NULL)
@@ -293,4 +366,4 @@ void rt_audio_pipe_destroy(struct rt_audio_pipe *pipe)
     return;
 }
 
-#endif /* RT_USING_HEAP */
+#endif /* RT_USING_HEAP */

+ 26 - 19
components/drivers/audio/dev_audio_pipe.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2023, RT-Thread Development Team
+ * Copyright (c) 2006-2025 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -20,7 +20,9 @@
 #define PIPE_BUFSZ    RT_PIPE_BUFSZ
 #endif
 
-/* portal device */
+/**
+ * @brief Portal device
+ */
 struct rt_audio_portal_device
 {
     struct rt_device parent;
@@ -28,38 +30,43 @@ struct rt_audio_portal_device
     struct rt_device *read_dev;
 };
 
+/**
+ * @brief Aduio pipe flags
+ */
 enum rt_audio_pipe_flag
 {
-    /* both read and write won't block */
-    RT_PIPE_FLAG_NONBLOCK_RDWR = 0x00,
-    /* read would block */
-    RT_PIPE_FLAG_BLOCK_RD = 0x01,
-    /* write would block */
-    RT_PIPE_FLAG_BLOCK_WR = 0x02,
-    /* write to this pipe will discard some data when the pipe is full.
-     * When this flag is set, RT_PIPE_FLAG_BLOCK_WR will be ignored since write
-     * operation will always be success. */
-    RT_PIPE_FLAG_FORCE_WR = 0x04,
+
+    RT_PIPE_FLAG_NONBLOCK_RDWR = 0x00, /**< both read and write won't block */
+    RT_PIPE_FLAG_BLOCK_RD = 0x01, /**< read would block */
+    RT_PIPE_FLAG_BLOCK_WR = 0x02, /**< write would block */
+    RT_PIPE_FLAG_FORCE_WR = 0x04, /**< write to this pipe will discard some data when the pipe is full.
+                                    * When this flag is set, RT_PIPE_FLAG_BLOCK_WR will be ignored since write
+                                    * operation will always be success. */
 };
 
+/**
+ * @brief Audio buffer info
+ *
+ * The preferred number and size of audio pipeline buffer for the audio device, it
+ * will be used in rt_audio_replay struct.
+ *
+ */
 struct rt_audio_pipe
 {
     struct rt_device parent;
 
-    /* ring buffer in pipe device */
-    struct rt_ringbuffer ringbuffer;
+    struct rt_ringbuffer ringbuffer; /**< ring buffer in pipe device */
 
     rt_int32_t flag;
 
-    /* suspended list */
-    rt_list_t suspended_read_list;
-    rt_list_t suspended_write_list;
+    rt_list_t suspended_read_list; /**< suspended thread list for reading */
+    rt_list_t suspended_write_list; /**< suspended thread list for writing  */
 
     struct rt_audio_portal_device *write_portal;
     struct rt_audio_portal_device *read_portal;
 };
 
-#define PIPE_CTRL_GET_SPACE          0x14            /**< get the remaining size of a pipe device */
+#define PIPE_CTRL_GET_SPACE          0x14 /**< get the remaining size of a pipe device */
 
 rt_err_t rt_audio_pipe_init(struct rt_audio_pipe *pipe,
                       const char *name,
@@ -72,4 +79,4 @@ rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size)
 void rt_audio_pipe_destroy(struct rt_audio_pipe *pipe);
 #endif /* RT_USING_HEAP */
 
-#endif /* __DEV_AUDIO_PIPE_H__ */
+#endif /* __DEV_AUDIO_PIPE_H__ */

+ 189 - 66
components/drivers/include/drivers/dev_audio.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2023, RT-Thread Development Team
+ * Copyright (c) 2006-2025 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -15,70 +15,156 @@
 
 #include "dev_audio_pipe.h"
 
-/* AUDIO command */
+/**
+ * @defgroup group_Audio Audio
+ *
+ * @ingroup group_Drivers RT-Thread Drivers
+ *
+ * @brief Audio driver API.
+ */
+
+/**
+ * @addtogroup group_Audio
+ * @{
+ */
+
+/**
+ * @defgroup audio_control AUDIO_CTL
+ *
+ * @brief Control audio device.
+ */
+
+/**
+ * @addtogroup audio_control
+ * @{
+ */
+
+/**
+ * @brief Generate audio command code with @a a
+ *
+ * @param[in] a offset of command.
+ *
+ * @return audio device control command code.
+ */
 #define _AUDIO_CTL(a) (RT_DEVICE_CTRL_BASE(Sound) + a)
 
-#define AUDIO_CTL_GETCAPS                   _AUDIO_CTL(1)
-#define AUDIO_CTL_CONFIGURE                 _AUDIO_CTL(2)
-#define AUDIO_CTL_START                     _AUDIO_CTL(3)
-#define AUDIO_CTL_STOP                      _AUDIO_CTL(4)
-#define AUDIO_CTL_GETBUFFERINFO             _AUDIO_CTL(5)
-
-/* Audio Device Types */
-#define AUDIO_TYPE_QUERY                    0x00
-#define AUDIO_TYPE_INPUT                    0x01
-#define AUDIO_TYPE_OUTPUT                   0x02
-#define AUDIO_TYPE_MIXER                    0x04
-
-/* Supported Sampling Rates */
-#define AUDIO_SAMP_RATE_8K                  0x0001
-#define AUDIO_SAMP_RATE_11K                 0x0002
-#define AUDIO_SAMP_RATE_16K                 0x0004
-#define AUDIO_SAMP_RATE_22K                 0x0008
-#define AUDIO_SAMP_RATE_32K                 0x0010
-#define AUDIO_SAMP_RATE_44K                 0x0020
-#define AUDIO_SAMP_RATE_48K                 0x0040
-#define AUDIO_SAMP_RATE_96K                 0x0080
-#define AUDIO_SAMP_RATE_128K                0x0100
-#define AUDIO_SAMP_RATE_160K                0x0200
-#define AUDIO_SAMP_RATE_172K                0x0400
-#define AUDIO_SAMP_RATE_192K                0x0800
-
-/* Supported Bit Rates */
-#define AUDIO_BIT_RATE_22K                  0x01
-#define AUDIO_BIT_RATE_44K                  0x02
-#define AUDIO_BIT_RATE_48K                  0x04
-#define AUDIO_BIT_RATE_96K                  0x08
-#define AUDIO_BIT_RATE_128K                 0x10
-#define AUDIO_BIT_RATE_160K                 0x20
-#define AUDIO_BIT_RATE_172K                 0x40
-#define AUDIO_BIT_RATE_192K                 0x80
-
-/* Support Dsp(input/output) Units controls */
-#define AUDIO_DSP_PARAM                     0           /* get/set all params */
-#define AUDIO_DSP_SAMPLERATE                1           /* samplerate */
-#define AUDIO_DSP_CHANNELS                  2           /* channels */
-#define AUDIO_DSP_SAMPLEBITS                3           /* sample bits width */
-
-/* Supported Mixer Units controls */
-#define AUDIO_MIXER_QUERY                   0x0000
-#define AUDIO_MIXER_MUTE                    0x0001
-#define AUDIO_MIXER_VOLUME                  0x0002
-#define AUDIO_MIXER_BASS                    0x0004
-#define AUDIO_MIXER_MID                     0x0008
-#define AUDIO_MIXER_TREBLE                  0x0010
-#define AUDIO_MIXER_EQUALIZER               0x0020
-#define AUDIO_MIXER_LINE                    0x0040
-#define AUDIO_MIXER_DIGITAL                 0x0080
-#define AUDIO_MIXER_MIC                     0x0100
-#define AUDIO_MIXER_VITURAL                 0x0200
-#define AUDIO_MIXER_EXTEND                  0x8000    /* extend mixer command */
+#define AUDIO_CTL_GETCAPS                   _AUDIO_CTL(1) /**< Get audio device capabilities */
+#define AUDIO_CTL_CONFIGURE                 _AUDIO_CTL(2) /**< Get audio device configuration */
+#define AUDIO_CTL_START                     _AUDIO_CTL(3) /**< Start audio device  */
+#define AUDIO_CTL_STOP                      _AUDIO_CTL(4) /**< Stop audio device */
+#define AUDIO_CTL_GETBUFFERINFO             _AUDIO_CTL(5) /**< Get audio device buffer information */
+
+/** @} */ /* End of audio_control*/
+
+/**
+ * @defgroup audio_type AUDIO_TYPE
+ *
+ * @brief Audio Device Types
+ */
+
+/**
+ * @addtogroup audio_type
+ * @{
+ */
+#define AUDIO_TYPE_QUERY                    0x00 /**< Query audio device type */
+#define AUDIO_TYPE_INPUT                    0x01 /**< Set audio device type to input type */
+#define AUDIO_TYPE_OUTPUT                   0x02 /**< Set audio device type to output type */
+#define AUDIO_TYPE_MIXER                    0x04 /**< Set audio device type to mixer type */
+/** @} */ /* End of audio_type*/
+
+/**
+ * @defgroup audio_samp_rates AUDIO_SAMP_RATES
+ *
+ * @brief Supported audio sample rates for the audio device.
+ */
+
+/**
+ * @addtogroup audio_samp_rates
+ * @{
+ */
+#define AUDIO_SAMP_RATE_8K                  0x0001 /**< Set audio device sample rate to 8K */
+#define AUDIO_SAMP_RATE_11K                 0x0002 /**< Set audio device sample rate to 11K */
+#define AUDIO_SAMP_RATE_16K                 0x0004 /**< Set audio device sample rate to 16K */
+#define AUDIO_SAMP_RATE_22K                 0x0008 /**< Set audio device sample rate to 22K */
+#define AUDIO_SAMP_RATE_32K                 0x0010 /**< Set audio device sample rate to 32K */
+#define AUDIO_SAMP_RATE_44K                 0x0020 /**< Set audio device sample rate to 44K */
+#define AUDIO_SAMP_RATE_48K                 0x0040 /**< Set audio device sample rate to 48K */
+#define AUDIO_SAMP_RATE_96K                 0x0080 /**< Set audio device sample rate to 96K */
+#define AUDIO_SAMP_RATE_128K                0x0100 /**< Set audio device sample rate to 128K */
+#define AUDIO_SAMP_RATE_160K                0x0200 /**< Set audio device sample rate to 160K */
+#define AUDIO_SAMP_RATE_172K                0x0400 /**< Set audio device sample rate to 172K */
+#define AUDIO_SAMP_RATE_192K                0x0800 /**< Set audio device sample rate to 192K */
+/** @} */ /* End of audio_samp_rates*/
+
+/**
+ * @defgroup audio_bit_rates AUDIO_BIT_RATES
+ *
+ * @brief Supported bit rates for the audio device.
+ */
+
+/**
+ * @addtogroup audio_bit_rates
+ * @{
+ */
+#define AUDIO_BIT_RATE_22K                  0x01 /**< Set audio device bit rates to 22K */
+#define AUDIO_BIT_RATE_44K                  0x02 /**< Set audio device bit rates to 44K */
+#define AUDIO_BIT_RATE_48K                  0x04 /**< Set audio device bit rates to 48K */
+#define AUDIO_BIT_RATE_96K                  0x08 /**< Set audio device bit rates to 96K */
+#define AUDIO_BIT_RATE_128K                 0x10 /**< Set audio device bit rates to 128K */
+#define AUDIO_BIT_RATE_160K                 0x20 /**< Set audio device bit rates to 160K */
+#define AUDIO_BIT_RATE_172K                 0x40 /**< Set audio device bit rates to 172K */
+#define AUDIO_BIT_RATE_192K                 0x80 /**< Set audio device bit rates to 192K */
+/** @} */ /* End of audio_bit_rates*/
+
+
+/**
+ * @defgroup audio_dsp AUDIO_DSP
+ *
+ * @brief Support Dsp(input/output) Units controls
+ */
+
+/**
+ * @addtogroup audio_dsp
+ * @{
+ */
+#define AUDIO_DSP_PARAM                     0 /**< get/set all params */
+#define AUDIO_DSP_SAMPLERATE                1 /**< samplerate */
+#define AUDIO_DSP_CHANNELS                  2 /**< channels */
+#define AUDIO_DSP_SAMPLEBITS                3 /**< sample bits width */
+/** @} */ /* End of audio_dsp*/
+
+/**
+ * @defgroup audio_mixer AUDIO_MIXER
+ *
+ * @brief Supported Mixer Units controls
+ */
+
+/**
+ * @addtogroup audio_mixer
+ * @{
+ */
+#define AUDIO_MIXER_QUERY                   0x0000 /**< Query mixer capabilities */
+#define AUDIO_MIXER_MUTE                    0x0001 /**< Mute audio device */
+#define AUDIO_MIXER_VOLUME                  0x0002 /**< Set mixer volume */
+#define AUDIO_MIXER_BASS                    0x0004 /**< Set the low-frequency section of the mixer */
+#define AUDIO_MIXER_MID                     0x0008 /**< Set the mid-frequency section of the mixer*/
+#define AUDIO_MIXER_TREBLE                  0x0010 /**< Set the high-frequency section of the mixer */
+#define AUDIO_MIXER_EQUALIZER               0x0020 /**< Set equalizer option */
+#define AUDIO_MIXER_LINE                    0x0040 /**< Set line control option */
+#define AUDIO_MIXER_DIGITAL                 0x0080 /**< Set digital source */
+#define AUDIO_MIXER_MIC                     0x0100 /**< Set microphone option */
+#define AUDIO_MIXER_VITURAL                 0x0200 /**< Set virtual audio option */
+#define AUDIO_MIXER_EXTEND                  0x8000 /**< Extend mixer command */
+/** @} */ /* End of audio_mixer*/
 
 #define AUDIO_VOLUME_MAX                    (100)
 #define AUDIO_VOLUME_MIN                    (0)
 
 #define CFG_AUDIO_REPLAY_QUEUE_COUNT        4
 
+/**
+ * @brief Audio stream control command
+ */
 enum
 {
     AUDIO_STREAM_REPLAY = 0,
@@ -86,7 +172,13 @@ enum
     AUDIO_STREAM_LAST = AUDIO_STREAM_RECORD,
 };
 
-/* the preferred number and size of audio pipeline buffer for the audio device */
+/**
+ * @brief Audio buffer info
+ *
+ * The preferred number and size of audio pipeline buffer for the audio device, it
+ * will be used in rt_audio_replay struct.
+ *
+ */
 struct rt_audio_buf_info
 {
     rt_uint8_t *buffer;
@@ -110,6 +202,13 @@ struct rt_audio_ops
     void (*buffer_info)(struct rt_audio_device *audio, struct rt_audio_buf_info *info);
 };
 
+/**
+ * @brief Audio configuration
+ *
+ * The preferred number and size of audio pipeline buffer for the audio device, it
+ * will be used in rt_audio_caps struct.
+ *
+ */
 struct rt_audio_configure
 {
     rt_uint32_t samplerate;
@@ -117,6 +216,9 @@ struct rt_audio_configure
     rt_uint16_t samplebits;
 };
 
+/**
+ * @brief Audio capabilities
+ */
 struct rt_audio_caps
 {
     int main_type;
@@ -130,6 +232,9 @@ struct rt_audio_caps
     } udata;
 };
 
+/**
+ * @brief Audio replay
+ */
 struct rt_audio_replay
 {
     struct rt_mempool *mp;
@@ -145,12 +250,18 @@ struct rt_audio_replay
     rt_bool_t activated;
 };
 
+/**
+ * @brief Audio record, the audio device pipe container of ringbuffer
+ */
 struct rt_audio_record
 {
     struct rt_audio_pipe pipe;
     rt_bool_t activated;
 };
 
+/**
+ * @brief Audio device
+ */
 struct rt_audio_device
 {
     struct rt_device           parent;
@@ -163,14 +274,26 @@ rt_err_t    rt_audio_register(struct rt_audio_device *audio, const char *name, r
 void        rt_audio_tx_complete(struct rt_audio_device *audio);
 void        rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len);
 
-/* Device Control Commands */
-#define CODEC_CMD_RESET             0
-#define CODEC_CMD_SET_VOLUME        1
-#define CODEC_CMD_GET_VOLUME        2
-#define CODEC_CMD_SAMPLERATE        3
-#define CODEC_CMD_EQ                4
-#define CODEC_CMD_3D                5
+/**
+ * @defgroup audio_codec_cmd CODEC_CMD
+ *
+ * @brief Device Control Commands
+ */
+
+/**
+ * @addtogroup audio_codec_cmd
+ * @{
+ */
+#define CODEC_CMD_RESET             0 /**< Reset audio device by codec */
+#define CODEC_CMD_SET_VOLUME        1 /**< Set volume by codec */
+#define CODEC_CMD_GET_VOLUME        2 /**< Get volume by codec */
+#define CODEC_CMD_SAMPLERATE        3 /**< Set sample rate by codec */
+#define CODEC_CMD_EQ                4 /**< Set equalizer by codec */
+#define CODEC_CMD_3D                5 /**< Set 3D effect by codec */
 
 #define CODEC_VOLUME_MAX            (63)
+/** @} */ /* End of audio_codec_cmd*/
+
+/** @} group_Audio */
 
-#endif /* __DEV_AUDIO_H__ */
+#endif /* __DEV_AUDIO_H__ */

+ 1 - 0
documentation/5.device/INDEX.md

@@ -12,3 +12,4 @@
 - @subpage page_device_watchdog
 - @subpage page_device_wlan
 - @subpage page_device_sensor
+- @subpage page_device_audio

+ 1 - 0
documentation/Doxyfile

@@ -870,6 +870,7 @@ INPUT                  = . \
                          ../components/finsh \
                          ../components/drivers/include/drivers \
                          ../components/drivers/clk \
+                         ../components/drivers/audio \
                          ../components/dfs/dfs_v2/src \
                          ../components/dfs/dfs_v2/include
 

+ 517 - 0
documentation/device/adudio/audio.md

@@ -0,0 +1,517 @@
+@page page_device_audio Audio Device
+
+# Audio Introduction
+
+The Audio device is a crucial component in embedded systems, responsible for audio data sampling and output. An Audio device typically consists of a data bus interface, control bus interface, audio codec (Codec), speaker, and microphone, as shown below:
+
+## API List
+
+For more details, see @ref group_Audio
+
+## Audio Device Features
+
+The RT-Thread Audio device driver framework serves as the underlying layer of the Audio framework. It handles raw audio data acquisition/output, audio stream control, device management, volume adjustment, and hardware/Codec abstraction.
+
+- **Interface**: Standard device interface (`open/close/read/control`).
+- **Synchronous access mode**.
+- **Supports playback and recording**.
+- **Audio parameter management**.
+- **Volume control**.
+
+# Accessing Audio Devices
+
+## Finding an Audio Device
+
+Applications obtain a device handle using the Audio device name. The device lookup function is as follows:
+
+```c
+rt_device_t rt_device_find(const char* name);
+```
+
+| **Parameter** | **Description**                       |
+|---------------|---------------------------------------|
+| name          | Audio device name                     |
+| **Return**    | ——                                   |
+| Device handle | Returns the handle if found           |
+| RT_NULL       | Device not found                      |
+
+Example usage:
+```c
+#define SOUND_DEVICE_NAME    "sound0"    /* Audio device name */
+
+static rt_device_t snd_dev;              /* Audio device handle */
+
+/* Find Audio device by name and obtain handle */
+snd_dev = rt_device_find(SOUND_DEVICE_NAME);
+```
+
+## Opening an Audio Device
+
+Applications can open/close devices using the device handle. To open a device:
+
+```c
+rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);
+```
+
+| **Parameter** | **Description**                                                                 |
+|---------------|---------------------------------------------------------------------------------|
+| dev           | Device handle                                                                   |
+| oflags        | Device mode flags                                                               |
+| **Return**    | ——                                                                             |
+| RT_EOK        | Device opened successfully                                                     |
+| -RT_EBUSY     | Device cannot be reopened if registered with `RT_DEVICE_FLAG_STANDALONE`        |
+| -RT_EINVAL    | Unsupported open flags                                                         |
+| Other errors  | Device open failure                                                            |
+
+Supported `oflags` values:
+```c
+#define RT_DEVICE_OFLAG_WRONLY      0x002     /* Write-only mode for playback devices */
+#define RT_DEVICE_FLAG_RDONLY       0x001     /* Read-only mode for recording devices */
+```
+
+Audio devices are categorized into playback (output) and recording (input). Playback devices use the write-only flag, while recording devices use read-only.
+
+Example for opening a playback device:
+```c
+rt_device_open(snd_dev, RT_DEVICE_OFLAG_WRONLY)
+```
+
+Example for opening a recording device:
+```c
+rt_device_open(mic_dev, RT_DEVICE_FLAG_RDONLY)
+```
+
+## Controlling an Audio Device
+
+Applications configure Audio devices using control commands:
+
+```c
+rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);
+```
+
+| **Parameter** | **Description**                               |
+|---------------|-----------------------------------------------|
+| dev           | Device handle                                 |
+| cmd           | Control command (see below)                   |
+| arg           | Control parameter (see below)                 |
+| **Return**    | ——                                           |
+| RT_EOK        | Operation succeeded                           |
+| -RT_ENOSYS    | Failed (null device handle)                   |
+| Other errors  | Operation failed                              |
+
+Supported control commands:
+```c
+/* AUDIO commands */
+#define _AUDIO_CTL(a) (0x10 + a)
+
+#define AUDIO_CTL_GETCAPS                   _AUDIO_CTL(1) /* Get device capabilities */
+#define AUDIO_CTL_CONFIGURE                 _AUDIO_CTL(2) /* Configure device */
+```
+
+Device capability structure:
+```c
+struct rt_audio_caps
+{
+    int main_type;                            /* Main command type */
+    int sub_type;                             /* Sub command type */
+
+    union
+    {
+        rt_uint32_t mask;
+        int     value;                       /* Parameter value */
+        struct rt_audio_configure config;    /* Audio configuration */
+    } udata;
+};
+```
+
+### Setting Playback Parameters
+
+Configure playback sample rate, channels, and bit depth:
+```c
+struct rt_audio_caps caps;
+
+caps.main_type               = AUDIO_TYPE_OUTPUT; /* Playback device */
+caps.sub_type                = AUDIO_DSP_PARAM;   /* Set all audio parameters */
+caps.udata.config.samplerate = 44100;             /* Sample rate */
+caps.udata.config.channels   = 2;                 /* Channels */
+caps.udata.config.samplebits = 16;                /* Bit depth */
+rt_device_control(device, AUDIO_CTL_CONFIGURE, &caps);
+```
+
+### Setting Playback Volume
+
+Adjust master playback volume (0-100):
+```c
+struct rt_audio_caps caps;
+
+caps.main_type   = AUDIO_TYPE_MIXER;       /* Volume control type */
+caps.sub_type    = AUDIO_MIXER_VOLUME;     /* Set master volume */
+caps.udata.value = volume;                 /* Range: 0-100 */
+rt_device_control(snd_dev, AUDIO_CTL_CONFIGURE, &caps);
+```
+
+### Setting Recording Parameters
+
+Configure recording sample rate, channels, and bit depth:
+```c
+struct rt_audio_caps caps;
+
+caps.main_type               = AUDIO_TYPE_INPUT;  /* Recording device */
+caps.sub_type                = AUDIO_DSP_PARAM;   /* Set all audio parameters */
+caps.udata.config.samplerate = 44100;             /* Sample rate */
+caps.udata.config.channels   = 2;                 /* Channels */
+caps.udata.config.samplebits = 16;                /* Bit depth */
+rt_device_control(device, AUDIO_CTL_CONFIGURE, &caps);
+```
+
+### Setting Recording Volume
+
+Adjust microphone gain (0-100):
+```c
+struct rt_audio_caps caps;
+
+caps.main_type = AUDIO_TYPE_MIXER;       /* Volume control type */
+caps.sub_type  = AUDIO_MIXER_MIC;        /* Set microphone gain */
+caps.udata.value = volume;               /* Range: 0-100 */
+rt_device_control(player->device, AUDIO_CTL_CONFIGURE, &caps);
+```
+
+## Writing Audio Data
+
+Write data to a playback device:
+```c
+rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size);
+```
+
+| **Parameter** | **Description**                               |
+|---------------|-----------------------------------------------|
+| dev           | Device handle                                 |
+| pos           | Unused (reserved for offset)                  |
+| buffer        | Data buffer to write                          |
+| size          | Data size to write                            |
+| **Return**    | ——                                           |
+| Bytes written | Actual bytes written (synchronous operation)  |
+
+This synchronous function writes data to the device's internal buffer. The call blocks when the buffer is full.
+
+## Reading Audio Data
+
+Read data from a recording device:
+```c
+rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size);
+```
+
+| **Parameter** | **Description**                               |
+|---------------|-----------------------------------------------|
+| dev           | Device handle                                 |
+| pos           | Unused (reserved for offset)                  |
+| buffer        | Buffer to store read data                     |
+| size          | Data size to read                             |
+| **Return**    | ——                                           |
+| Bytes read    | Actual bytes read (synchronous operation)     |
+| 0             | Check thread's errno for error status         |
+
+This synchronous function reads data from the device's internal pipe. The call blocks if insufficient data is available.
+
+## Closing an Audio Device
+
+Close the device after operations:
+```c
+rt_err_t rt_device_close(rt_device_t dev);
+```
+
+| **Parameter** | **Description**                       |
+|---------------|---------------------------------------|
+| dev           | Device handle                         |
+| **Return**    | ——                                   |
+| RT_EOK        | Device closed successfully           |
+| -RT_ERROR     | Device already closed                 |
+| Other errors  | Close failure                        |
+
+# Audio Device Usage Example
+
+Audio devices are used for playback and recording, often accompanied by audio file encoding and decoding. Below are examples of playing and recording WAV files. The complete code can be obtained from the [RT-Thread WAV Player Package](https://github.com/RT-Thread-packages/wavplayer).
+
+## Playback
+
+The main steps to play an audio file are as follows:
+
+1. First, find the Audio device and obtain the device handle.
+2. Open the Audio device in write-only mode.
+3. Set audio parameters (sampling rate, channels, etc.).
+4. Decode the audio file data.
+5. Write the audio file data.
+6. After playback is complete, close the device.
+
+```c
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <dfs_posix.h>
+
+#define BUFSZ   1024
+#define SOUND_DEVICE_NAME    "sound0"    /* Audio device name */
+static rt_device_t snd_dev;              /* Audio device handle */
+
+struct RIFF_HEADER_DEF
+{
+    char riff_id[4];     // 'R','I','F','F'
+    uint32_t riff_size;
+    char riff_format[4]; // 'W','A','V','E'
+};
+
+struct WAVE_FORMAT_DEF
+{
+    uint16_t FormatTag;
+    uint16_t Channels;
+    uint32_t SamplesPerSec;
+    uint32_t AvgBytesPerSec;
+    uint16_t BlockAlign;
+    uint16_t BitsPerSample;
+};
+
+struct FMT_BLOCK_DEF
+{
+    char fmt_id[4];    // 'f','m','t',' '
+    uint32_t fmt_size;
+    struct WAVE_FORMAT_DEF wav_format;
+};
+
+struct DATA_BLOCK_DEF
+{
+    char data_id[4];     // 'R','I','F','F'
+    uint32_t data_size;
+};
+
+struct wav_info
+{
+    struct RIFF_HEADER_DEF header;
+    struct FMT_BLOCK_DEF   fmt_block;
+    struct DATA_BLOCK_DEF  data_block;
+};
+
+int wavplay_sample(int argc, char **argv)
+{
+    int fd = -1;
+    uint8_t *buffer = NULL;
+    struct wav_info *info = NULL;
+    struct rt_audio_caps caps = {0};
+
+    if (argc != 2)
+    {
+        rt_kprintf("Usage:\n");
+        rt_kprintf("wavplay_sample song.wav\n");
+        return 0;
+    }
+
+    fd = open(argv[1], O_RDONLY);
+    if (fd < 0)
+    {
+        rt_kprintf("open file failed!\n");
+        goto __exit;
+    }
+
+    buffer = rt_malloc(BUFSZ);
+    if (buffer == RT_NULL)
+        goto __exit;
+
+    info = (struct wav_info *) rt_malloc(sizeof * info);
+    if (info == RT_NULL)
+        goto __exit;
+
+    if (read(fd, &(info->header), sizeof(struct RIFF_HEADER_DEF)) <= 0)
+        goto __exit;
+    if (read(fd, &(info->fmt_block),  sizeof(struct FMT_BLOCK_DEF)) <= 0)
+        goto __exit;
+    if (read(fd, &(info->data_block), sizeof(struct DATA_BLOCK_DEF)) <= 0)
+        goto __exit;
+
+    rt_kprintf("wav information:\n");
+    rt_kprintf("samplerate %d\n", info->fmt_block.wav_format.SamplesPerSec);
+    rt_kprintf("channel %d\n", info->fmt_block.wav_format.Channels);
+
+    /* Find the Audio device by name and obtain the device handle */
+    snd_dev = rt_device_find(SOUND_DEVICE_NAME);
+
+    /* Open the Audio playback device in write-only mode */
+    rt_device_open(snd_dev, RT_DEVICE_OFLAG_WRONLY);
+
+    /* Set audio parameters such as sampling rate, channels, and bit depth */
+    caps.main_type               = AUDIO_TYPE_OUTPUT;                           /* Output type (playback device) */
+    caps.sub_type                = AUDIO_DSP_PARAM;                             /* Set all audio parameters */
+    caps.udata.config.samplerate = info->fmt_block.wav_format.SamplesPerSec;    /* Sampling rate */
+    caps.udata.config.channels   = info->fmt_block.wav_format.Channels;         /* Channels */
+    caps.udata.config.samplebits = 16;                                          /* Bit depth */
+    rt_device_control(snd_dev, AUDIO_CTL_CONFIGURE, &caps);
+
+    while (1)
+    {
+        int length;
+
+        /* Read audio data from the file system */
+        length = read(fd, buffer, BUFSZ);
+
+        if (length <= 0)
+            break;
+
+        /* Write audio data to the Audio device */
+        rt_device_write(snd_dev, 0, buffer, length);
+    }
+
+    /* Close the Audio device */
+    rt_device_close(snd_dev);
+
+__exit:
+
+    if (fd >= 0)
+        close(fd);
+
+    if (buffer)
+        rt_free(buffer);
+
+    if (info)
+        rt_free(info);
+
+    return 0;
+}
+
+MSH_CMD_EXPORT(wavplay_sample,  play wav file);
+```
+
+## Recording
+
+The main steps to record an audio file are as follows:
+
+1. First, find the Audio device and obtain the device handle.
+2. Open the Audio device in read-only mode.
+3. Set audio parameters (sampling rate, channels, etc.).
+4. Read data from the Audio device.
+5. Process the recorded data.
+6. After recording is complete, close the device.
+
+```c
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <dfs_posix.h>
+
+#define RECORD_TIME_MS      5000
+#define RECORD_SAMPLERATE   16000
+#define RECORD_CHANNEL      2
+#define RECORD_CHUNK_SZ     ((RECORD_SAMPLERATE * RECORD_CHANNEL * 2) * 20 / 1000)
+
+#define SOUND_DEVICE_NAME    "mic0"      /* Audio device name */
+static rt_device_t mic_dev;              /* Audio device handle */
+
+struct wav_header
+{
+    char  riff_id[4];              /* "RIFF" */
+    int   riff_datasize;           /* RIFF chunk data size, excluding riff_id[4] and riff_datasize, total - 8 */
+    char  riff_type[4];            /* "WAVE" */
+    char  fmt_id[4];               /* "fmt " */
+    int   fmt_datasize;            /* fmt chunk data size, 16 for PCM */
+    short fmt_compression_code;    /* 1 for PCM */
+    short fmt_channels;            /* 1(mono) or 2(stereo) */
+    int   fmt_sample_rate;         /* samples per second */
+    int   fmt_avg_bytes_per_sec;   /* sample_rate * channels * bit_per_sample / 8 */
+    short fmt_block_align;         /* number of bytes per sample, bit_per_sample * channels / 8 */
+    short fmt_bit_per_sample;      /* bits of each sample(8,16,32). */
+    char  data_id[4];              /* "data" */
+    int   data_datasize;           /* data chunk size, pcm_size - 44 */
+};
+
+static void wavheader_init(struct wav_header *header, int sample_rate, int channels, int datasize)
+{
+    memcpy(header->riff_id, "RIFF", 4);
+    header->riff_datasize = datasize + 44 - 8;
+    memcpy(header->riff_type, "WAVE", 4);
+    memcpy(header->fmt_id, "fmt ", 4);
+    header->fmt_datasize = 16;
+    header->fmt_compression_code = 1;
+    header->fmt_channels = channels;
+    header->fmt_sample_rate = sample_rate;
+    header->fmt_bit_per_sample = 16;
+    header->fmt_avg_bytes_per_sec = header->fmt_sample_rate * header->fmt_channels * header->fmt_bit_per_sample / 8;
+    header->fmt_block_align = header->fmt_bit_per_sample * header->fmt_channels / 8;
+    memcpy(header->data_id, "data", 4);
+    header->data_datasize = datasize;
+}
+
+int wavrecord_sample(int argc, char **argv)
+{
+    int fd = -1;
+    uint8_t *buffer = NULL;
+    struct wav_header header;
+    struct rt_audio_caps caps = {0};
+    int length, total_length = 0;
+
+    if (argc != 2)
+    {
+        rt_kprintf("Usage:\n");
+        rt_kprintf("wavrecord_sample file.wav\n");
+        return -1;
+    }
+
+    fd = open(argv[1], O_WRONLY | O_CREAT);
+    if (fd < 0)
+    {
+        rt_kprintf("open file for recording failed!\n");
+        return -1;
+    }
+    write(fd, &header, sizeof(struct wav_header));
+
+    buffer = rt_malloc(RECORD_CHUNK_SZ);
+    if (buffer == RT_NULL)
+        goto __exit;
+
+    /* Find the Audio device by name and obtain the device handle */
+    mic_dev = rt_device_find(SOUND_DEVICE_NAME);
+    if (mic_dev == RT_NULL)
+        goto __exit;
+
+    /* Open the Audio recording device in read-only mode */
+    rt_device_open(mic_dev, RT_DEVICE_OFLAG_RDONLY);
+
+    /* Set audio parameters such as sampling rate, channels, and bit depth */
+    caps.main_type               = AUDIO_TYPE_INPUT;                            /* Input type (recording device) */
+    caps.sub_type                = AUDIO_DSP_PARAM;                             /* Set all audio parameters */
+    caps.udata.config.samplerate = RECORD_SAMPLERATE;                           /* Sampling rate */
+    caps.udata.config.channels   = RECORD_CHANNEL;                              /* Channels */
+    caps.udata.config.samplebits = 16;                                          /* Bit depth */
+    rt_device_control(mic_dev, AUDIO_CTL_CONFIGURE, &caps);
+
+    while (1)
+    {
+        /* Read 20ms of audio data from the Audio device */
+        length = rt_device_read(mic_dev, 0, buffer, RECORD_CHUNK_SZ);
+
+        if (length)
+        {
+            /* Write the audio data to the file system */
+            write(fd, buffer, length);
+            total_length += length;
+        }
+
+        if ((total_length / RECORD_CHUNK_SZ) >  (RECORD_TIME_MS / 20))
+            break;
+    }
+
+    /* Rewrite the WAV file header */
+    wavheader_init(&header, RECORD_SAMPLERATE, RECORD_CHANNEL, total_length);
+    lseek(fd, 0, SEEK_SET);
+    write(fd, &header, sizeof(struct wav_header));
+    close(fd);
+
+    /* Close the Audio device */
+    rt_device_close(mic_dev);
+
+__exit:
+    if (fd >= 0)
+        close(fd);
+
+    if (buffer)
+        rt_free(buffer);
+
+    return 0;
+}
+MSH_CMD_EXPORT(wavrecord_sample, record voice to a wav file);
+```
+