當您嘗試使用 USB API 直接存取 USB 音訊週邊裝置時, 有助於解決 AI 問題這些問題可能包括:安全性問題、限制媒體 可透過其他應用程式播放,以及關閉鬧鐘、通知和鈴聲 USB 裝置。
如要改善音訊播放品質,請改為設定 Mixer 屬性。
設定 Mixer 屬性
使用
AudioMixerAttributes
API
您可以在 USB 上為應用程式設定偏好的混合器屬性。
您的應用程式播放內容符合編碼格式、頻道遮罩和範例 偏好混合器屬性的速率,播放會附加在音訊上 輸出串流,但該輸出串流設定了偏好的混合器屬性。
應用程式可以透過任何設定串流至硬體抽象化 以及傳輸至裝置上,前提是 USB 裝置必須支援 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定
AudioMixerAttributes
中允許的兩種混音器行為為 DEFAULT
和
BIT_PERFECT
。如果混合器行為為 DEFAULT
,代表音訊
來自不同來源的資料
當混合器行為為 BIT_PERFECT
時,系統不會調整音訊混音、音量調整,
或音訊處理效果資料傳送形式為
位於 HAL 部分
最後前往 USB 裝置
使用 BIT_PERFECT
可讓你直接串流播放內容
數位 (DSD) 管理 Android 裝置。
以下程式碼範例說明如何完成這項作業:
val EXPECTED_FORMAT: AudioFormat = AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_24BIT_PACKED)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setSampleRate(44100)
.build()
fun startPlayback() {
// Query all supported mixer attributes
val mixerAttributesList: List<AudioMixerAttributes?> =
mAudioManager.getSupportedMixerAttributes(usbDevice)
// Find the wanted mixer attributes
val mixerAttributes = mixerAttributesList.stream()
.filter { mixerAttr: AudioMixerAttributes? ->
EXPECTED_FORMAT.equals(
mixerAttr!!.format
)
}
.findAny()
.orElse(null)
// Register a listener to mixer attributes changed
val listener = MyPreferredMixerAttributesChangedListener()
mAudioManager.addOnPreferredMixerAttributesChangedListener(
Executors.newSingleThreadExecutor(), listener
)
// Currently, only media usage over USB devices will be allowed
val attr: AudioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA).build()
// Set preferred mixer attributes
mAudioManager.setPreferredMixerAttributes(
attr, usbDevice, mixerAttributes
)
// Start playback, note the playback and the audio format must
// match what is set when calling `setPreferredMixerAttriutes`
// API.
val audioTrack = AudioTrack.Builder()
.setAudioAttributes(attr)
.setAudioFormat(mixerAttributes!!.format)
.build()
// Clear all preferred mixer attributes related stuff when
// playback task is completed
mAudioManager.clearPreferredMixerAttributes(attr, usbDevice)
mAudioManager.removeOnPreferredMixerAttributesChangedListener(listener)
}
private class MyPreferredMixerAttributesChangedListener :
AudioManager.OnPreferredMixerAttributesChangedListener {
override fun onPreferredMixerAttributesChanged(
attributes: AudioAttributes,
device: AudioDeviceInfo,
mixerAttributes: AudioMixerAttributes?,
) {
// Do something when preferred mixer attributes changed
}
}
final AudioFormat EXPECTED_FORMAT = new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_24BIT_PACKED)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setSampleRate(44100)
.build();
void startPlayback() {
// Query all supported mixer attributes
List<AudioMixerAttributes> mixerAttributesList =
mAudioManager.getSupportedMixerAttributes(usbDevice);
// Find the wanted mixer attributes
AudioMixerAttributes mixerAttributes =
mixerAttributesList.stream()
.filter(mixerAttr -> EXPECTED_FORMAT.equals(mixerAttr.getFormat()))
.findAny()
.orElse(null);
// Register a listener to mixer attributes changed
MyPreferredMixerAttributesChangedListener listener =
new MyPreferredMixerAttributesChangedListener();
mAudioManager.addOnPreferredMixerAttributesChangedListener(
Executors.newSingleThreadExecutor(), listener);
// Currently, only media usage over USB devices will be allowed
AudioAttributes attr = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA).build();
// Set preferred mixer attributes
mAudioManager.setPreferredMixerAttributes(
attr, usbDevice, mixerAttributes);
// Start playback, note the playback and the audio format must
// match what is set when calling `setPreferredMixerAttriutes`
// API.
AudioTrack audioTrack = new AudioTrack.Builder()
.setAudioAttributes(attr)
.setAudioFormat(mixerAttributes.getFormat())
.build();
// Clear all preferred mixer attributes related stuff when
// playback task is completed
mAudioManager.clearPreferredMixerAttributes(attr, usbDevice);
mAudioManager.removeOnPreferredMixerAttributesChangedListener(
listener);
}
private class MyPreferredMixerAttributesChangedListener
implements AudioManager.OnPreferredMixerAttributesChangedListener {
@Override
public void onPreferredMixerAttributesChanged(
AudioAttributes attributes,
AudioDeviceInfo device,
AudioMixerAttributes mixerAttributes) {
// Do something when preferred mixer attributes changed
}
}