2013-04-18 3 views
2

Я нашел здесь на stackoverflow.com a great example, который фактически работает для воспроизведения звуков. Все работает плавно, но я хотел бы знать, что произойдет в генерации PCM. Вот код:Создать звук - PCM (Android - Java)

int idx = 0; 
for (final double dVal : sample) { 
    final short val = (short) ((dVal * 32767)); 

    generatedSnd[idx++] = (byte) (val & 0x00ff); 
    generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
} 

, где образец представляет собой двойной массив, который содержит синус, вычисленный со всеми требуемыми параметрами в этом случае (частота, Гц, так далее и тому подобное), и generatedSnd является массивом байт. Все, что я знаю, это то, что val & 0xff переводит int в байт, но вот что конкретно сделано? Почему есть сдвиг >>> 8?

+0

Просто гадать ... Он сохраняет младший 8-бит в первом байте, затем он сохраняет более высокий 8-бит (от 9 до 16) во втором байте? Правильно ли это? Тогда что означает dVal * 32676? –

ответ

4

Вы не упомянули в своем вопросе, какой вход для этой функции есть, но я собираюсь угадать, что элементы в sample имеют диапазон от -1,0 до +1,0.

16-разрядные данные PCM имеют диапазон от -32768 до +32767. Итак, что происходит в этом методе, так это то, что каждый образец с плавающей запятой масштабируется на 32767, чтобы получить значение в диапазоне от -32767 до +32767, которое затем усекается до short.

Этого short затем сохраняются в generatedSnd (который я принимаю быть byte[]) сначала путем записи низкой byte из short (наименее значимых 8 бит), за которыми следуют старшим байты (сдвиг короткие 8 бит право берет то, что первоначально было высоким байтом, и помещает его в младший байт).

+0

Ваша догадка правильная, элементы образца имеют диапазон, о котором вы говорили. Большое спасибо за хорошее объяснение! EDIT: generateSnd был байтом [numSamples * 2], как вы сказали –