USB API'lerini kullanarak USB ses çevre birimine doğrudan erişmeye çalıştığınızda sorunlar oluşur. Bu sorunlar arasında güvenlik sorunları, diğer uygulamalardan
Ses çalmayı iyileştirmek için bunun yerine mikser özelliklerini yapılandırın.
Mikser özelliklerini yapılandırın
AudioMixerAttributes
API'lerini kullanarak uygulamanızı USB yerine tercih edilen mikser özellikleriyle yapılandırabilirsiniz.
Uygulama oynatmanız, tercih edilen mikser özelliklerinin kodlama biçimi, kanal maskesi ve örnek hızıyla eşleştiğinde, oynatma, mikseri tercih edilen mikser özellikleriyle yapılandırılan ses çıkış akışına eklenir.
Uygulamanız, USB cihaz yapılandırmayı desteklediği sürece herhangi bir yapılandırmada donanım soyutlama katmanına (HAL) ve cihaza akış gerçekleştirebilir.
AudioMixerAttributes
politikasında izin verilen iki mikser davranışı: DEFAULT
ve BIT_PERFECT
. Mikser davranışı DEFAULT
olduğunda, farklı kaynaklardan gelen ses verilerinin karıştırıldığını gösterir.
Mikser davranışı BIT_PERFECT
olduğunda, oynatmaya ses miksleme, ses ayarı veya işlenen ses efekti uygulanmaz. Veriler olduğu gibi HAL'ye, son olarak da USB cihazına gönderilir.
BIT_PERFECT
özelliğini kullanarak Android destekli cihazlarda dijital yayın (DSD) üzerinden nabız kodu modülasyonu (PCM) üzerinden doğrudan yayın yapabilirsiniz.
Aşağıdaki kod örneğinde bunun nasıl yapılacağı gösterilmektedir:
Kotlin
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 } }
Java
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 } }