Подтвердить что ты не робот

Несоответствия выборки 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 кГц. Таким образом, передачa > 192 кГц в 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() идентичный частоте дискретизации, переданной в конструктор?

4b9b3361

Ответ 1

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

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

Или услышать его от инженера Google