В ваших комментариях говорится, что в коде подразумевается порядок байтов.
Технически вы на самом деле выводите в порядке с прямым порядком байтов, однако это не имеет значения, потому что благодаря счастливой причуде ваш самый значимый байт всегда равен 0.
РЕДАКТИРОВАТЬ: чтобы объяснить это далее - когда ваше значение имеет максимальное значение 127, вы должны писать (0x00, 0x7f), но фактический вывод из вашего кода (0x7f, 0x00), который равен 32512. Это происходит быть около правильного 16 бит максимальное значение 32767, но с младшими 8 битами все ноль. Было бы лучше всегда использовать 32767 в качестве максимального значения, а затем отбросить 8 младших битов, если требуется.
Это означает, что даже если вы выводите 16-битные данные, эффективное разрешение составляет всего 8 бит. Это, кажется, объясняет отсутствие качества звука.
Я сделал версию вашего кода, которая просто выгружает необработанные данные в файл и не видит ничего плохого в самом сдвиге битов. Там нет неожиданных изменений знака или пропущенных битов, но есть шум в соответствии с качеством 8-битной выборки.
Кроме того, математика будет проще, если вы вычислите волновое уравнение на основе отсчетов выборок, а затем отдельно позаботитесь о смещении байтов:
int samples = 2 << 19;
byte audioBuffer[] = new byte[samples * channels * sampleSizeInBytes];
for ( int i = 0, j = 0; i < samples; ++i )
{
int wave = (int)(32767.0 * Math.sin(2.0 * Math.PI * frequency * i / sampleRate));
byte msb = (byte)(wave >>> 8);
byte lsb = (byte) wave;
for (int c = 0; c < channels; ++c) {
audioBuffer[j++] = msb;
if (sampleSizeInBytes > 1) {
audioBuffer[j++] = lsb;
}
}
}