Несоответствия выборки AudioTrack

Используя AudioTrack для воспроизведения, мне иногда нужно перепрограммировать звук, который не соответствует частоте дискретизации, поддерживаемой AudioTrack. При этом мне нужно определить максимальную частоту дискретизации, поддерживаемую AudioTrack под текущим устройством, в соответствии с текущей конфигурацией звука.

Из-за допустимого уровня дискретизации для AudioTrack, который плохо документирован, я решил отследить исходный код AudioTrack и нашел эту ошеломляющую линию:

 private static final int SAMPLE_RATE_HZ_MAX = 96000; 

Казалось бы, экземпляр AudioTrack применяет жесткий предел 96 кГц, независимо от фактических возможностей воспроизведения устройства.

Более запутанным является класс AudioFormat , в котором я перехожу к конструктору (API 21) AudioTrack , который содержит эту строку:

 if ((sampleRate <= 0) || (sampleRate > 192000)) { 

В его setSampleRate() . Теперь это жесткий предел 192 кГц . Таким образом, передача> 192 кГц в AudioFormat (или его построитель) приведет к AudioFormat IllegalArgumentException из AudioFormat и передаче настроенной 192 кГц <x <96 кГц частоты дискретизации AudioFormat в AudioTrack также вызовет исключение IllegalArgumentException .


То, что я обнаружил, в наибольшей степени запутанным, – это метод getNativeOutputSampleRate() в AudioTrack, который действительно возвращает правильную частоту дискретизации вывода (ну, не удивительно, учитывая, что она запускается непосредственно из собственного уровня, но такая непоследовательная).

И только для того, чтобы это сделать, метод setPlaybackRate() который утверждает:

Действительный диапазон частоты дискретизации составляет от 1 Гц до дважды значения, возвращаемого getNativeOutputSampleRate (int).

И действительно, я это пробовал, и это работает? Рассмотрим следующий фрагмент:

 int nativeRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC); android.util.Log.i("UI", "Native stream rate: " + nativeRate + " Hz"); // Build audio attributes AudioAttributes.Builder attribBuilder = new AudioAttributes.Builder(); attribBuilder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC); attribBuilder.setUsage(AudioAttributes.USAGE_MEDIA); AudioAttributes attrib = attribBuilder.build(); // Build audio format AudioFormat.Builder afBuilder = new AudioFormat.Builder(); afBuilder.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO); afBuilder.setEncoding(AudioFormat.ENCODING_PCM_16BIT); afBuilder.setSampleRate(nativeRate); try{ AudioTrack trackTest = new AudioTrack(attrib, afBuilder.build(), nativeRate, AudioTrack.MODE_STREAM, 0); android.util.Log.i("UI", "Track created successfully (direct)"); }catch(Exception ex){ android.util.Log.w("UI", "Failed to create AudioTrack at native rate!"); // Use a random supported samplerate to get pass constructor afBuilder.setSampleRate(48000); try{ AudioTrack trackTest = new AudioTrack(attrib, afBuilder.build(), nativeRate, AudioTrack.MODE_STREAM, 0); trackTest.setPlaybackRate(nativeRate); android.util.Log.i("UI", "Track created successfully (indirect)"); }catch(Exception e){ android.util.Log.w("UI", "Failed to create AudioTrack at 48 KHz"); } } 

После потока программы, когда нативная частота дискретизации <96 кГц , код печатает:

Собственная скорость потока: 48000 Гц
Трек создан успешно (прямой)

Но, когда я подключаю внешний ЦАП с возможностью воспроизведения до 192 кГц , я получаю:

Собственная скорость потока: 192000 Гц
Не удалось создать AudioTrack с нужной скоростью!
Трек создан успешно (непрямой)

Что с этими несоответствиями? И есть, setPlaybackRate() идентичный частоте дискретизации, переданной в конструктор?

Solutions Collecting From Web of "Несоответствия выборки AudioTrack"

В настоящее время большинство телефонов Android на рынке поддерживают только одну частоту дискретизации. Я считаю, что некоторые Samsung играют на частоте 48 кГц, и почти все остальные играют на частоте 44,1 кГц. Эти значения продиктованы аппаратными средствами, и хотя есть возможность изменить собственный коэффициент, его функция заключается в вторичном доказательстве в будущем, но в основном для 2. resample ALL audio во время выполнения в ПРОГРАММНОМ ОБЕСПЕЧЕНИИ. Это дорогостоящая задача, а также несколько разрушительная. Причина, по которой существует жесткий предел на частоте 192 кГц (= 2 * 96 кГц), вероятна, потому что отправка более чем в два раза максимальной частоты (96 кГц) представляет собой огромную трату ресурсов, так как вы можете просто выбросить каждый второй образец, чтобы эффективно уменьшить В 2 раза, пока вы не находитесь в этом диапазоне.

Лучше избегать указания неродной частоты дискретизации. Он будет перепрограммирован в программном обеспечении и в лучшем случае будет пустой тратой ресурсов и, в худшем случае, источником задержки.

Или послушайте его от инженера Google