Commit 21fb70d
authored
feat(android): Add configurable audio sample rate with smart defaults (flutter-webrtc#1967)
## Problem
When using `bypassVoiceProcessing=true` for high-quality audio scenarios
(music streaming, voice avatars, etc.), the audio output sample rate
defaults to whatever `WebRtcAudioManager` queries from the system. This
can be 8kHz or 16kHz depending on audio mode, causing poor audio quality
even when the Opus codec is configured for 48kHz - the decoded 48kHz
audio gets resampled down to 8kHz/16kHz before output.
## Solution
This PR adds configurable audio sample rate support with smart defaults:
1. **New initialization options:**
- `audioSampleRate`: Sets both input and output sample rate (Hz)
- `audioOutputSampleRate`: Sets only output sample rate (takes
precedence)
2. **Smart default behavior:**
- When `bypassVoiceProcessing=true` and no explicit sample rate is set,
automatically queries and uses the device's native optimal sample rate
via `AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE`
- Falls back to 48000 Hz if native sample rate cannot be determined
- Only applies when `bypassVoiceProcessing=true` to maintain backward
compatibility
## Usage Examples
```dart
// Automatic (recommended): uses device's native optimal rate
await WebRTC.initialize(bypassVoiceProcessing: true);
// -> Automatically uses 48000 Hz (or device's optimal rate)
// Explicit output sample rate
await WebRTC.initialize(audioOutputSampleRate: 48000);
// Both input and output
await WebRTC.initialize(audioSampleRate: 16000);
// Combined example
await WebRTC.initialize(
bypassVoiceProcessing: true,
audioOutputSampleRate: 48000, // Override the automatic detection
);
```
## Benefits
- ✅ **High-quality audio by default** when `bypassVoiceProcessing` is
enabled
- ✅ **Device-adaptive**: Uses each Android device's native optimal
sample rate
- ✅ **Backward compatible**: Only affects behavior when
`bypassVoiceProcessing=true`
- ✅ **Configurable**: Allows explicit override for specific use cases
(telephony at 16kHz, music at 48kHz, etc.)
- ✅ **Solves real-world issues**: Fixes poor audio quality in music
streaming apps, AI voice avatars, and other high-fidelity audio
applications
## Technical Details
### Changes Made
**Dart API** (`lib/src/native/utils.dart`):
- Added documentation for `audioSampleRate` and `audioOutputSampleRate`
parameters
**Android Implementation**
(`android/src/main/java/com/cloudwebrtc/webrtc/MethodCallHandlerImpl.java`):
- Parse `audioSampleRate` and `audioOutputSampleRate` from
initialization options
- Query device's native optimal sample rate using
`AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE`
- Apply sample rate to `JavaAudioDeviceModule.Builder` via:
- `.setSampleRate(int)` for both input/output
- `.setOutputSampleRate(int)` for output only
- Smart default: Use native rate when `bypassVoiceProcessing=true` with
no explicit config
### Testing
Tested on Android devices with:
- LiveAvatar AI (48kHz Opus stereo) - **audio quality significantly
improved**
- Device native rates: 48000 Hz (most common)
- Fallback behavior verified when AudioManager unavailable
### Backward Compatibility
- ✅ No breaking changes
- ✅ Default behavior unchanged when `bypassVoiceProcessing=false`
- ✅ Only activates new behavior when explicitly using
`bypassVoiceProcessing=true`
## Related Issues
This addresses audio quality issues reported by users trying to
implement:
- Music streaming applications
- AI voice avatar integrations (LiveAvatar, ElevenLabs, etc.)
- High-fidelity audio conferencing
- Audio playback scenarios requiring > 16kHz quality
## Screenshots/Logs
**Before** (without fix):
```
FlutterWebRTCPlugin: [No sample rate configuration - defaults to 8kHz/16kHz]
Opus Codec: clockRate=48000, channels=2 ✓
Audio Output: 8000 Hz ✗ (resampled down!)
```
**After** (with fix):
```
FlutterWebRTCPlugin: bypassVoiceProcessing enabled with no explicit sample rate - using device's native optimal rate: 48000 Hz
Opus Codec: clockRate=48000, channels=2 ✓
Audio Output: 48000 Hz ✓ (matches codec!)
```1 parent 94cbae9 commit 21fb70d
File tree
2 files changed
+55
-2
lines changed- android/src/main/java/com/cloudwebrtc/webrtc
- lib/src/native
2 files changed
+55
-2
lines changedLines changed: 48 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
184 | 185 | | |
185 | 186 | | |
186 | 187 | | |
187 | | - | |
| 188 | + | |
188 | 189 | | |
189 | 190 | | |
190 | 191 | | |
| |||
241 | 242 | | |
242 | 243 | | |
243 | 244 | | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
244 | 278 | | |
245 | 279 | | |
246 | 280 | | |
| |||
376 | 410 | | |
377 | 411 | | |
378 | 412 | | |
379 | | - | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
380 | 426 | | |
381 | 427 | | |
382 | 428 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
57 | 64 | | |
58 | 65 | | |
59 | 66 | | |
| |||
0 commit comments