мы не можем просто отменить проверку элемента, чтобы просто включить поддерживаемые элементы, например:
if (deviceIsIOS &&
targetElement.setSelectionRange &&
(
targetElement.type === 'text' ||
targetElement.type === 'search' ||
targetElement.type === 'password' ||
targetElement.type === 'url' ||
targetElement.type === 'tel'
)
) {
вместо этого:
if (deviceIsIOS &&
targetElement.setSelectionRange &&
targetElement.type.indexOf('date') !== 0 &&
targetElement.type !== 'time' &&
targetElement.type !== 'month'
) {
Первый вопрос, который я вижу, это произвольная частота дискретизации.
AudioTrack.getNativeOutputSampleRate
вернет частоту дискретизации, используемую звуковой системой. Это может быть 44100, 48000, 96000, 192000 или что угодно. Но похоже, что у вас есть аудиоданные из какого-то независимого источника, который производит данные по очень точной частоте дискретизации.
Предположим, что аудиоданные из источника выбраны с частотой 44100 выборок в секунду. Если вы начнете воспроизводить его на 96000, он будет ускорен и выше.
Итак, используйте настройку частоты дискретизации, а также количество каналов, формат выборки и т. Д., Как это указано источником, а не полагаясь на системные значения по умолчанию.
Второе: вы уверены, что процедура readData
всегда будет достаточно быстрой, чтобы успешно заполнить буфер, каков бы ни был небольшой буфер, и вернуться назад быстрее, чем буфер воспроизводится?
Вы создали AudioTrack с AudioTrack.getMinBufferSize , переданным как параметр bufferSizeInBytes
.
Функция getMinBufferSize
возвращает минимальный возможный размер буфера, который можно использовать при этом параметре. Предположим, что он возвращает размер, соответствующий буфере длиной 10 мс. Это означает, что новые данные должны быть подготовлены в течение этого временного интервала. То есть Временной интервал между предыдущим write
возвратом элемента управления и новым write
будет меньше, чем размер времени буфера.
Итак, если функция readData
может задерживаться по какой-то причине дольше, чем этот промежуток времени воспроизведение будет приостановлено на это время, вы услышите небольшие пробелы в воспроизведении.
Причины, по которым readData
могут задерживаться, могут быть различными: если он считывает данные из файла, то это может задержать ожидание операций ввода-вывода; если он выделяет java-объекты, он может быть наложен на задержку сборщика мусора; если он использует какой-то декодер другого типа источника звука, который использует собственную буферизацию, он может периодически задерживать перезарядку буфера.
Но в любом случае, если вы не создаете синтезатор реального времени который должен как можно скорее реагировать на ввод пользователя, всегда используйте размер буфера, достаточно высокий, но не менее getMinBufferSize
. I.e.:
sampleRate = 44100;// sampling rate of the source
int bufSize = sampleRate * 4; // 1 second length; 4 - is the frame size: 2 chanels * 2 bytes per each sample
bufSize = max(bufSize, AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT)); // Not less than getMinBufferSize returns
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
bufSize,
AudioTrack.MODE_STREAM);
Как и пользователь @pskink,
Скорее всего, ваш sampleRate (или любой другой параметр, переданный конструктору AudioTrack) недействителен.
blockquote>Итак, я начните с проверки того, какое значение вы фактически устанавливаете для частоты дискретизации.
Для справки вы также можете установить скорость
AudioTrack
, вызвав методsetPlayBackParams
:public void setPlaybackParams (PlaybackParams params)
Если вы проверите документы AudioTrack docs , вы увидите документы PlaybackParams и можете установить скорость и pitch выходного аудио. Затем этот объект можно передать, чтобы установить параметры воспроизведения в вашем объекте AudioTrack.
Однако маловероятно, что вам нужно будет использовать это, если ваша единственная проблема - это исходный конструктор
sampleRate
(поскольку мы не можем см., откуда происходит переменнаяsampleRate
).
shortBuffer.length
вы должны указать точное количество данных, возвращаемых функциейreadData
. Поэтому, еслиreadData
заполняет только часть буфера, тогда он должен каким-то образом вернуть количество фактических данных. – AterLux 13 July 2018 в 15:47readData
заполняет массив. И определенно не передавать пустые массивы методуwrite
. – AterLux 13 July 2018 в 23:10