2014-09-15 4 views
3

Я ищу для преобразования Float32Array в Int16Array.Преобразование Float32Array в Int16Array

Вот что у меня (я не предоставляю data).

var data = ...; /*new Float32Array();*/ 
    var dataAsInt16Array = new Int16Array(data.length); 
    for(var i=0; i<data.length; i++){ 
    dataAsInt16Array[i] = parseInt(data[i]*32767,10); 
    } 

Я не уверен, что делаю это правильно и ищет какое-то направление.

ответ

3

Вы можете сделать это прямо из ArrayBuffer

var dataAsInt16Array = new Int16Array(data.buffer); 

var f32 = new Float32Array(4); 
f32[0] = 0.1, f32[1] = 0.2, f32[2] = 0.3, f32[3] = 0.4; 
// [0.10000000149011612, 0.20000000298023224, 0.30000001192092896, 0.4000000059604645] 

var i16 = new Int16Array(f32.buffer); 
// [-13107, 15820, -13107, 15948, -26214, 16025, -13107, 16076] 

// and back again 
new Float32Array(i16.buffer); 
// [0.10000000149011612, 0.20000000298023224, 0.30000001192092896, 0.4000000059604645] 
+0

Проголосовали за этот ответ, но потом я понял, что это неправильно. Буфер Float32Array представляет собой массив необработанных байтов. Обработка необработанных 32-битных байтов в виде целых чисел является чем-то странным. –

+0

@ SergeyP.akaazure Это то, что ОП просил –

3

Если вы после преобразования сырых базовых данных вы можете использовать подход Paul S. описывает в своем ответе ,

Но имейте в виду, что вы не получите то же самое номеров, поскольку вы имеете дело с 32-разрядным представлением числа IEEE 754 в случае Float32. Когда используется новое представление, такое как Int16, вы смотрите на двоичное представление этого, а не на исходное число.

Если вы после номера вам придется конвертировать вручную, просто изменить свой код:

var data = ...; /*new Float32Array();*/ 
var len = data.length, i = 0; 
var dataAsInt16Array = new Int16Array(len); 

while(i < len) 
    dataAsInt16Array[i] = convert(data[i++]); 

function convert(n) { 
    var v = n < 0 ? n * 32768 : n * 32767;  // convert in range [-32768, 32767] 
    return Math.max(-32768, Math.min(32768, v)); // clamp 
} 
1
var floatbuffer = audioProcEvent.inputBuffer.getChannelData(0); 
    var int16Buffer = new Int16Array(floatbuffer.length); 

    for (var i = 0, len = floatbuffer.length; i < len; i++) { 
     if (floatbuffer[i] < 0) { 
      int16Buffer[i] = 0x8000 * floatbuffer[i]; 
     } else { 
      int16Buffer[i] = 0x7FFF * floatbuffer[i]; 
     } 
    } 
0

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

Прямой способ преобразования Float32Array в Int16Array так просто, как

var a = new Int16Array(myFloat32Array); 

Для обработки данных можно использовать подход, который вы указали в вопросе. Я не уверен, есть ли необходимость звонить parseInt.

0

В ECMAScript 2015 и далее есть TypedArray.from, который преобразует любой типизированный массив (и, действительно, любой итерабельный) в указанный тип типизированного массива.

Так преобразование Float32Array к Uint8Array теперь так же просто, как:

const floatArray = new Float32Array() 
const intArray = Int16Array.from(floatArray) 

... хотя и с усечением.

Смежные вопросы