Use an external audio source instead of the device microphone
Describes how to implement custom audio capture with the AOQ Client SDK, including adding external audio streams, pushing PCM data, and managing stream lifecycle.
The AOQ Client SDK's built-in audio module covers basic audio needs, but in some scenarios the built-in capture module may not be sufficient. Custom audio capture is useful when you need to:
Coming soon.
Start audio capture first. External audio stream data is mixed with internal capture data before being published. If you don't need internal microphone capture, set
Once the
Parameters:
Implement your own audio capture or data source for your use case, then feed the data into the SDK. Common data sources include:
Call
Important notes:
When custom capture is no longer needed, stop the push loop first, then call
Overview
The AOQ Client SDK's built-in audio module covers basic audio needs, but in some scenarios the built-in capture module may not be sufficient. Custom audio capture is useful when you need to:
- Work around audio capture device conflicts.
- Feed audio data from a custom capture system or audio file into the SDK for transmission.
- Publish AI TTS-generated audio through the SDK.
Sample code
Coming soon.
Prerequisites
- An engine instance has been created by calling
createEngine. - A connection to the server has been established (the
onConnectionStatusChangecallback has reportedAoqConnectionStatusConnected).
Implementation
1. Start or stop audio capture
Start audio capture first. External audio stream data is mixed with internal capture data before being published. If you don't need internal microphone capture, set isExternal=true to disable the internal capture device.
2. After connecting, add the external audio stream
Once the onConnectionStatusChange callback reports AoqConnectionStatusConnected, call addAudioExternalStream to add the external audio stream. Assign a unique streamId that you will use to push data and manage the stream.
If you need 3A processing (echo cancellation, noise suppression, automatic gain control), set the enable3A parameter in AoqAudioExternalStreamConfig.
| Parameter | Type | Default | Description |
|---|---|---|---|
| trackType | AoqTrackType | AoqTrackTypeAudio | Audio track type |
| codecType | AoqEncoderType | AoqEncoderTypeAudioPCM | Audio stream format |
| channels | int | 1 | Channel count |
| sampleRate | int | 48000 | Sample rate (Hz) |
| playoutVolume | int | 100 | Playback volume [0-100] |
| publishVolume | int | 100 | Publishing volume [0-100] |
| maxBufferDuration | int | 1000 | Maximum buffer duration (milliseconds) |
| enable3A | boolean | false | Whether to apply 3A processing to input PCM |
3. Capture or obtain PCM data
Implement your own audio capture or data source for your use case, then feed the data into the SDK. Common data sources include:
- Microphone capture: Use Android AudioRecord to capture PCM data.
- File reading: Parse PCM data from a local PCM or WAV audio file.
- AI TTS: Obtain PCM data from a speech synthesis engine.
- Network stream: Decode PCM data from a network audio stream.
AoqAudioFrameData object.
4. Push audio data to the SDK via the stream ID
Call pushAudioExternalStreamData to feed the captured PCM data into the SDK.
- For hardware capture: use 10 ms per frame and call push whenever data is available.
- For file-based input: use 40 ms per frame and sleep 30 ms between pushes.
- Maintain a
runningflag. Exit the push loop when the engine exits or the stream ID is removed.
- Start pushing data only after the connection is established and the external audio stream has been added.
- Set
AoqAudioFrameData'snumOfSamplesto match the actual length of the data. pushAudioExternalStreamDatamay fail if the internal buffer is full (error code 110). Retry after a short delay.- For real-time capture, use 10 ms frames and call push whenever data is available. Handle error code 110.
- For file-based input, use 40 ms frames and call push every 30 ms. Handle error code 110.
- Before the engine exits (
destroy) or a stream ID is removed, setmPushRunning = falseto stop the push loop and avoid accessing released resources.
5. Remove the external audio stream
When custom capture is no longer needed, stop the push loop first, then call removeAudioExternalStream to remove the external audio stream.