오디오 재생 개선

USB API를 사용하여 USB 오디오 주변기기에 직접 액세스하려고 할 때 문제가 발생합니다 이러한 문제에는 보안 문제, 미디어 제한 등이 포함될 수 있습니다. 재생, 알람, 알림, 벨소리가 다운됨 USB 기기.

오디오 재생을 개선하려면 대신 믹서 속성을 구성하세요.

믹서 속성 구성

AudioMixerAttributes API, USB를 통해 선호하는 믹서 속성으로 앱을 구성할 수 있습니다.

앱 재생이 인코딩 형식, 채널 마스크, 샘플과 일치하는 경우 기본 믹서 속성의 비트 전송률이 아니라 믹서가 기본 믹서 속성으로 구성된 출력 스트림입니다.

앱은 모든 구성에서 하드웨어 추상화로 스트리밍할 수 있습니다. 단, USB 장치가 구성할 수 있습니다

AudioMixerAttributes에 허용되는 두 가지 믹서 동작은 DEFAULTBIT_PERFECT입니다. 믹서 동작이 DEFAULT이면 오디오가 서로 다른 소스의 데이터가 혼합되어 있습니다

믹서 동작이 BIT_PERFECT이면 오디오 믹싱, 볼륨 조정 없음, 오디오 처리 효과가 적용되는지 확인합니다. 데이터는 HAL에 전달되고 마지막으로 USB 기기로 연결됩니다.

BIT_PERFECT를 사용하면 스트림을 연결할 수 있습니다. Android 구동 기기에서 DSD(Over pulse Code Modulation)를 지원합니다. 다음 코드 샘플은 이를 실행하는 방법을 보여줍니다.

KotlinJava
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
   
}
}