> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 qrb_ros_audio_service 播放和录制音频

> qrb_ros_audio_service 是一个提供核心音频功能的 ROS 包。它作为 ROS 生态系统中音频播放和录制的主要接口。

* QRB ROS Audio Service：一个 ROS 节点，创建服务服务器，响应应用的请求，并将其转换为对 Audio Manager 的操作。

* QRB ROS Audio Common：一个 ROS 节点，作为 QRB ROS Audio Service 和 QRB Audio Common Lib 之间的桥梁。

* QRB Audio Manager：根据流配置执行由 Audio Service 提供的音频操作。

* QRB Audio Common Lib：通过调用 PulseAudio API 提供音频功能。

## 管道流程

下图展示了 `qrb_ros_audio_service` 的管道流程。

<Frame caption="qrb_ros_audio_service 管道。">
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/SDKs/QIR-SDK-Ubuntu/images/image20.png" style={{width: "70%"}} alt="Application client calling the audio service, which drives the audio common node, audio manager, and common library over the mic and speaker hardware." />
</Frame>

## `qrb_ros_audio_service` API

下表列出了 `qrb_ros_audio_service` 提供的 ROS 接口。

| 接口      | 名称               | 类型                                              | 说明                         |
| ------- | ---------------- | ----------------------------------------------- | -------------------------- |
| Service | `/audio_service` | `qrb_ros_audio_service_msgs::srv::AudioRequest` | 允许 ROS 应用发送用于音频播放和录制的服务请求。 |

## `qrb_ros_audio_common` API

`qrb_ros_audio_common` 包公开了 ROS 参数、ROS 接口以及 `qrb_audio_common_lib` API。使用它们设置播放和捕获流，并从你自己的节点控制它们。

### ROS 参数

下表列出了 `qrb_ros_audio_common` 的 ROS 参数，包括每个参数的类型、说明和默认值。

| 名称            | 类型       | 说明                                           | 默认值              |
| ------------- | -------- | -------------------------------------------- | ---------------- |
| `Stream_type` | `string` | 指定动作的流类型：`playback` 用于音频播放，`capture` 用于音频录制。 | `default_stream` |
| `action_name` | `string` | 指定动作的名称。                                     | `default_action` |
| `topic_name`  | `string` | 指定话题的名称。                                     | `default_topic`  |

### ROS 接口

下表列出了 `qrb_ros_audio_common` 的 ROS 接口，包括每个接口的名称、类型和用途。

| 接口         | 名称                    | 类型                                               | 说明                                                      |
| ---------- | --------------------- | ------------------------------------------------ | ------------------------------------------------------- |
| Action     | `/ros_audio_playback` | `qrb_ros_audio_common_msgs::action::AudioCommon` | 播放功能的动作，通过 `action_name` 参数指定动作名。                       |
| Action     | `/ros_audio_capture`  | `qrb_ros_audio_common_msgs::action::AudioCommon` | 录制功能的动作，通过 `action_name` 参数指定动作名。                       |
| Subscriber | `/qrb_audiodata`      | `qrb_ros_audio_common_msgs::msg::AudioData`      | 用于流式音频播放。订阅来自该节点的原始音频数据。你可以使用 `--topic_name` 参数更改话题名。   |
| Publisher  | `/qrb_audiodata`      | `qrb_ros_audio_common_msgs::msg::AudioData`      | 用于流式音频录制。在录制过程中发布实时原始音频数据。你可以使用 `--topic_name` 参数更改话题名。 |

### `qrb_audio_common_lib` API

下表列出了 `qrb_audio_common_lib` API，包括每个函数的参数和行为。

| 函数                                                                                                             | 参数                                                                         | 说明                         |
| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------- |
| `uint32_t audio_stream_open(const audio_stream_info & stream_info, stream_event_callback_func event_callback)` | • `stream_info`：指定流配置的结构体。<br />• `stream_event_callback_func`：回调函数。       | 打开流。成功时返回 `stream_handle`。 |
| `int audio_stream_start(uint32_t stream_handle)`                                                               | `stream_handle`：流的唯一标识符。                                                   | 启动流。成功时返回 0。               |
| `int audio_stream_mute(uint32_t stream_handle, bool mute)`                                                     | • `stream_handle`：流的唯一标识符。<br />• `mute`：指示是否将流静音的布尔标志。                    | 将流静音或取消静音。成功时返回 0。         |
| `int audio_stream_stop(uint32_t stream_handle)`                                                                | `stream_handle`：流的唯一标识符。                                                   | 停止流。成功时返回 0。               |
| `size_t audio_stream_write(uint32_t stream_handle, size_t length, void * buf)`                                 | • `stream_handle`：流的唯一标识符。<br />• `length`：写入的大小。<br />• `buf`：指向数据缓冲区的指针。 | 将缓冲区写入以播放流。返回实际写入的长度。      |

## 前提条件

你已根据[安装 QIR SDK](./install-the-qir-sdk)完成设备设置，并在设备上安装了 ROS2 Jazzy 和 Qualcomm Intelligent Robotics (QIR) SDK。

## 开箱即用运行 `qrb_ros_audio_service`

<Steps>
  <Step title="安装 qrb_ros_audio_service 包">
    ```bash Install the packages theme={null}
    sudo apt install ros-jazzy-qrb-ros-audio-common ros-jazzy-qrb-ros-audio-service
    ```
  </Step>

  <Step title="启动 qrb_ros_audio_service 节点">
    a. 终端 1：Audio common 包

    ```bash theme={null}
    source /opt/ros/jazzy/setup.bash
    ros2 launch qrb_ros_audio_common component.launch.py
    ```

    b. 终端 2：Audio service

    ```bash theme={null}
    source /opt/ros/jazzy/setup.bash
    ros2 launch qrb_ros_audio_service audio_service.launch.py
    ```
  </Step>

  <Step title="将音乐文件推送到设备路径">
    将音乐文件推送到设备路径，例如 `/tmp/xxx.wav`。
  </Step>

  <Step title="播放音乐">
    a. 获取用于音乐录制和播放的 `audio_service_test.py` 脚本。

    ```bash theme={null}
    wget https://raw.githubusercontent.com/qualcomm-qrb-ros/qrb_ros_audio_service/main/tests/audio_service_test.py
    ```

    b. 选择以下操作之一来测试音频服务。

    * 分步播放（通过扬声器输出声音）。

      ```bash theme={null}
      source /opt/ros/jazzy/setup.bash
      python3 audio_service_test.py --type='playback' --source='/tmp/xxx.wav' --volume=100
      ```

    * 分步录制（从麦克风录制声音输入并保存到文件）。

      ```bash theme={null}
      source /opt/ros/jazzy/setup.bash
      python3 audio_service_test.py --type='record' --source='/tmp/rec.wav' --channels=1 --sample_rate=16000 --sample_format=16
      ```

    * 流式播放。

      ```bash theme={null}
      source /opt/ros/jazzy/setup.bash
      python3 audio_service_test.py --type='playback' --channels=1 --sample_rate=16000 --sample_format=16 --pub_pcm=True --volume=100 --topic_name='loopback'
      ```

    * 流式录制。

          <Note>
            如果你同时启动流式播放和流式录制，声音将从麦克风回环到扬声器。
          </Note>

      ```bash theme={null}
      source /opt/ros/jazzy/setup.bash
      python3 audio_service_test.py --type='record' --source='/tmp/rec.wav' --channels=1 --sample_rate=16000 --sample_format=16 --topic_name='loopback'
      ```
  </Step>
</Steps>

## 从源码构建

<Steps>
  <Step title="安装依赖">
    ```bash Install the dependencies theme={null}
    sudo apt install build-essential cmake pkg-config
    # Install ROS2 Jazzy (if not already installed)
    # Follow instructions at https://docs.ros.org/en/jazzy/Installation.html
    sudo apt install ros-jazzy-rclcpp ros-jazzy-rclcpp-components ros-jazzy-ament-cmake-auto ros-jazzy-std-msgs libpulse-dev libsndfile1-dev
    ```
  </Step>

  <Step title="下载源码并使用 colcon 构建">
    ```bash Build the packages theme={null}
    cd ~/ros2_ws/src
    git clone https://github.com/qualcomm-qrb-ros/qrb_ros_audio_service.git
    cd ~/ros2_ws
    colcon build
    ```
  </Step>

  <Step title="运行和调试">
    ```bash Run the test script theme={null}
    source install/setup.bash
    source /opt/ros/jazzy/setup.bash
    python3 audio_service_test.py --type='playback' --source='/tmp/xxx.wav' --volume=100
    ```
  </Step>
</Steps>
