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

# Enable core audio with qrb_ros_audio_service

The `qrb_ros_audio_service` sample application is a ROS package that delivers core audio functionalities, serving as the primary interface for audio capabilities (currently supporting playback and recording) within the ROS ecosystem.

<Note>
  **Note**

  For more information, see the [qrb\_ros\_audio\_service](https://github.com/qualcomm-qrb-ros/qrb_ros_audio_service) GitHub repo.
</Note>

## Pipeline for `qrb_ros_audio_service`

<img
  src="https://mintcdn.com/qualcomm-staging/blZpKs_b9On5nj-y/archives/2.1/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/qrb_ros_audio_service_pipeline-regenerate.svg?fit=max&auto=format&n=blZpKs_b9On5nj-y&q=85&s=68d5f80d0275e5e05d2387a56e7de16b"
  style={{
width: "70%",
display: "block",
margin: "0 auto" }}
  width="713"
  height="474"
  data-path="archives/2.1/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/qrb_ros_audio_service_pipeline-regenerate.svg"
/>

<p style={{ textAlign: 'center', fontWeight: 'bold' }}>
  Figure: qrb\_ros\_audio\_service pipeline
</p>

## ROS nodes/services used in the `qrb_ros_audio_service `pipeline

| **ROS node** | **Description** |
| :-: | :-: |
| `/audio_service` | This node functions as the primary entry point for the `qrb_ros_audio_service`, offering audio playback and recording capabilities through ROS service requests. |

| **ROS service** | **Type** | **Description** |
| :-: | :-: | :-: |
| `/audio_server` | `qrb_ros_audio_service_msgs::srv::AudioRequest` | Allows ROS applications to send service requests for audio playback and recording. |

## ROS topics used in the `qrb_ros_audio_service `pipeline

| **ROS topic** | **Type** | **Description** |
| :-: | :-: | :-: |
| `/qrb_audiodata` | `qrb_ros_audio_service_msgs::msg::AudioData` | Used for streaming audio playback and recording. Publishes the recorded real-time raw audio data, or allows subscription to this node's raw data for playback. You can modify the topic name using the `--topic_name` parameter. Supports using separate topics for playback and recording operations. |

## Prerequisites

You have **Set up the device** according to [Set up the environment for running sample applications](./set-up-env-for-sample-app).

## Run out-of-the-box `qrb_ros_audio_service`

<Accordion title="Try me">
  <Steps>
    <Step title="Set up the environment">
      Start three commandline terminals on your device and run the following commands.

      ```bash theme={null}
      ssh root@[ip-addr]
      ```

      ```bash title="SSH Session" theme={null}
      export HOME=/home
      source /usr/share/qirp-setup.sh
      ```
    </Step>

    <Step title="Run the audio service">
      In the first SSH terminal, run the audio service package using the `ros2 launch` command.

      ```bash title="SSH Session" theme={null}
      ros2 launch qrb_ros_audio_service audio_service.launch.py
      ```
    </Step>

    <Step title="Check the default devices for the pipewire">
      1. Verify the status of default speaker and handset mic.
         ```bash title="SSH Session" theme={null}
         wpctl status
         ```
         ```text theme={null}
         Audio
          ├─ Devices:
          │
          ├─ Sinks:
          │      * 42. pal sink speaker ll         [vol: 1.00]
          │        44. pal sink speaker_db         [vol: 1.00]
          │        46. pal sink headset_ll         [vol: 1.00]
          │        47. pal sink headset_db         [vol: 1.00]
          ├─ Sources:
          │      * 48. pal source handset mic      [vol: 1.00]
          │        50. pal source headset mic      [vol: 1.00]
         ```
      2. If the default speaker or handset mic isn't set, use `wpctl set-default <device-num>` to set the default device(s).
         ```bash title="SSH Session" theme={null}
         # Set the default speaker
         wpctl set-default 42
         # Set the default handset mic
         wpctl set-default 48
         ```
    </Step>

    <Step title="Run the test cases">
      In the third SSH terminal, run the test cases using either ROS commands or Python scripts according to the following table.

      <Note>
        **Note**

        For all step-by-step test cases, `stream_handle` indicates the stream created by the audio service when the command is `create`.

        After the audio service creates a stream, the command prints the value of `stream_handle` in the third SSH terminal.

        * For the ROS command, you see the following output:
          > `stream_handle=<***>`
        * For the Python script, you see the following output: `command create success 1 stream_handle <***>.` Download the Python script using
          ```bash theme={null}
          wget https://raw.githubusercontent.com/qualcomm-qrb-ros/qrb_ros_audio_service/main/tests/audio_service_test.py
          ```
      </Note>

      <table>
        <caption>Table: Audio service commands</caption>

        <thead>
          <tr>
            <th style={{ width: '16.7%' }}>Case name</th>
            <th style={{ width: '16.7%' }}>Description</th>
            <th style={{ width: '66.7%' }}>ROS command/Python script</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td>One-touch playback</td>
            <td>Start playback with a one-touch command. The speaker outputs the audio. Supports the WAV file format. Place the music file on a device path, for example, `/tmp/music.wav`.</td>

            <td>
              <Tabs>
                <Tab title="ROS command">
                  ```bash theme={null}
                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "play",
                  source: "/tmp/music.wav",
                  volume: 100,
                  }"
                  ```
                </Tab>

                <Tab title="Python script">
                  ```python theme={null}
                  python3 audio_service_test.py --mode one-touch --type playback --source /tmp/music.wav --volume 100
                  ```
                </Tab>
              </Tabs>
            </td>
          </tr>

          <tr>
            <td>Step-by-step playback</td>
            <td>Start playback with step-by-step commands. The speaker outputs the audio. Supports the WAV file format.</td>

            <td>
              <Tabs>
                <Tab title="ROS command">
                  ```bash theme={null}
                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  type: "playback",
                  command: "create",
                  source: "/tmp/music.wav",
                  volume: 100,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "start",
                  stream_handle: <stream_handle>,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "mute",
                  mute: true,
                  stream_handle: <stream_handle>,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "mute",
                  mute: false,
                  stream_handle: <stream_handle>,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "stop",
                  stream_handle: <stream_handle>,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "release",
                  stream_handle: <stream_handle>,
                  }"
                  ```
                </Tab>

                <Tab title="Python script">
                  ```python theme={null}
                  # Create and start the stream (step-by-step mode automatically starts after create)
                  python3 audio_service_test.py --mode step-by-step --type playback --source /tmp/music.wav --volume 100

                  # In another terminal, mute the stream using the printed stream_handle
                  python3 audio_service_test.py --set-mute --stream_handle <stream_handle> --mute true

                  # Unmute the stream
                  python3 audio_service_test.py --set-mute --stream_handle <stream_handle> --mute false

                  # Press Ctrl+C in the first terminal to stop and release the stream
                  ```
                </Tab>
              </Tabs>
            </td>
          </tr>

          <tr>
            <td>Streaming playback</td>
            <td>Create and start a streaming playback. It subscribes to the audio PCM data from the `loopback` topic. Audio data should be filled with `qrb_ros_audio_service_msgs::msg::AudioData`.</td>

            <td>
              <Tabs>
                <Tab title="ROS command">
                  Start a step-by-step streaming playback:

                  ```bash theme={null}
                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  audio_info: {
                  channels: 1,
                  sample_rate: 16000,
                  sample_format: 16,
                  },
                  type: "playback",
                  command: "create",
                  volume: 100,
                  topic_name: "loopback",
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "start",
                  stream_handle: <stream_handle>,
                  }"
                  ```

                  Start a one-touch streaming playback:

                  ```bash theme={null}
                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  audio_info: {
                  channels: 1,
                  sample_rate: 16000,
                  sample_format: 16,
                  },
                  command: "play",
                  volume: 100,
                  topic_name: "loopback",
                  }"
                  ```
                </Tab>

                <Tab title="Python script">
                  Start a step-by-step streaming playback:

                  ```python theme={null}
                  python3 audio_service_test.py --mode step-by-step --type playback --channels 1 --sample_rate 16000 --sample_format 16 --volume 100 --topic_name loopback
                  ```

                  Start a one-touch streaming playback:

                  ```python theme={null}
                  python3 audio_service_test.py --mode one-touch --type playback --channels 1 --sample_rate 16000 --sample_format 16 --volume 100 --topic_name loopback
                  ```
                </Tab>
              </Tabs>
            </td>
          </tr>

          <tr>
            <td>Step-by-step record</td>
            <td>Use the default input device to record with step-by-step commands and write the audio data to the `/tmp/rec.wav` file.</td>

            <td>
              <Tabs>
                <Tab title="ROS command">
                  ```bash theme={null}
                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  audio_info: {
                  channels: 1,
                  sample_rate: 16000,
                  sample_format: 16,
                  },
                  type: "record",
                  command: "create",
                  source: "/tmp/rec.wav",
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "start",
                  stream_handle: <stream_handle>,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "stop",
                  stream_handle: <stream_handle>,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "release",
                  stream_handle: <stream_handle>,
                  }"
                  ```
                </Tab>

                <Tab title="Python script">
                  ```python theme={null}
                  # Create and start the recording stream (step-by-step mode automatically starts after create)
                  python3 audio_service_test.py --mode step-by-step --type record --channels 1 --sample_rate 16000 --sample_format 16 --source /tmp/rec.wav

                  # Press Ctrl+C to stop and release the stream
                  ```
                </Tab>
              </Tabs>
            </td>
          </tr>

          <tr>
            <td>Publish recording data</td>

            <td>
              * Publish the recording data to a topic (default topic name: `qrb_audiodata`. You can specify another name using `topic_name`).
              * The audio data will be filled with `qrb_ros_audio_service_msgs::msg::AudioData`.
            </td>

            <td>
              <Tabs>
                <Tab title="ROS command">
                  Publish the recording data to a topic (default topic name is "`qrb_audiodata`", but it can be specified using `topic_name`):

                  ```bash theme={null}
                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  audio_info: {
                  channels: 1,
                  sample_rate: 16000,
                  sample_format: 16,
                  },
                  type: "record",
                  command: "create",
                  pub_pcm: true,
                  topic_name: "loopback",
                  }"
                  ```

                  Or, publish the recording data to `/qrb_audiodata`. Meanwhile, save it to a file:

                  ```bash theme={null}
                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  audio_info: {
                  channels: 1,
                  sample_rate: 16000,
                  sample_format: 16,
                  },
                  type: "record",
                  command: "create",
                  pub_pcm: true,
                  source: "/tmp/rec.wav",
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{command: "start",
                  stream_handle: <stream_handle>,
                  }"

                  ros2 topic echo /qrb_audiodata

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "stop",
                  stream_handle: <stream_handle>,
                  }"

                  ros2 service call /audio_server qrb_ros_audio_service_msgs/srv/AudioRequest "{
                  command: "release",
                  stream_handle: <stream_handle>,
                  }"
                  ```
                </Tab>

                <Tab title="Python script">
                  Publish the recording data to a topic (default topic name is "`qrb_audiodata`", but it can be specified using `--topic_name`):

                  ```python theme={null}
                  python3 audio_service_test.py --mode step-by-step --type record --channels 1 --sample_rate 16000 --sample_format 16 --pub_pcm true --topic_name loopback
                  ```

                  Or, publish the recording data to `/qrb_audiodata`. Meanwhile, save it to a file:

                  ```python theme={null}
                  python3 audio_service_test.py --mode step-by-step --type record --channels 1 --sample_rate 16000 --sample_format 16 --pub_pcm true --source /tmp/rec.wav
                  ```

                  In another terminal, echo the topic:

                  ```python theme={null}
                  ros2 topic echo /qrb_audiodata
                  ```

                  Press Ctrl+C in the first terminal to stop and release the stream.
                </Tab>
              </Tabs>
            </td>
          </tr>
        </tbody>
      </table>
    </Step>
  </Steps>
</Accordion>
