Первый вопрос, который я вижу, это произвольная частота дискретизации.
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);
Используйте flex
вместо height
для своих детей flexbox.
body{
display: flex;
flex-direction: column;
justify-content: stretch;
flex-wrap: wrap;
height: 100vh;
width: 100vw;
margin: 0;
}
header{
background-color: white;
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
width:100vw;
flex: 0 0 10vh;
margin: 0;
}
main{
background-color: #f1f1f1;
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
width: 100vw;
flex: 1;
margin: 0;
}
footer{
background-color: #666666;
flex: 0 0 4vh;
width: 100vw;
}
<body>
<header>
<div id="headercontentwrapper">
<div id="logowrapper"></div>
<div id="navwrapper"></div>
</div>
</header>
<main>
<div id="contentwrapper">
<div id="contentheaderwrapper"></div>
<div id="actualcontentwrapper"></div>
</div>
</main>
<footer>
</footer>
</body>
Как я уже сказал в своем комментарии, ваш код выглядит нормально, может, есть что-то еще, что вызывает проблемы?
пс: я сделал фрагмент и исправил ваши теги
body {
display: flex;
flex-direction: column;
justify-content: start;
flex-wrap: wrap;
height: 100vh;
width: 100vw;
margin: 0;
}
header {
background-color: white;
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
width: 100vw;
height: 10vh;
margin: 0;
}
main {
background-color: #f1f1f1;
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
width: 100vw;
height: 85vh;
margin: 0;
}
footer {
background-color: #666666;
height: 4vh;
width: 100vw;
}
<html>
<head>
</head>
<body>
<header>
<div id="headercontentwrapper">
<div id="logowrapper"></div>
<div id="navwrapper"></div>
</div>
</header>
<main>
<div id="contentwrapper">
<div id="contentheaderwrapper"></div>
<div id="actualcontentwrapper"></div>
</div>
</main>
<footer>
</footer>
</body>
</html>
Просто удалите height: 85vh;
из своей основной, и все в порядке. Проблема в том, что ваше тело имеет высоту 100vh, а главное - 85vh. Вот почему между главным и нижним колонтитулами был «huuuuuge margin»;)
Надеюсь, это помогло!