简体   繁体   English

在 Javascript 中读取带符号的 16 位数据

[英]Reading signed 16 bit data in Javascript

I have been banging my head to solve this:我一直在敲我的头来解决这个问题:

I received a raw data from an embeded device.我从嵌入式设备收到了原始数据。 From the documentation, the way to read it into a single value is:从文档中,将其读入单个值的方法是:

Every two bytes of data can be combined to a single raw wave value.Its value is a signed 16-bit integer that ranges from -32768 to 32767. The first byte of the Value represents the high-order byte of the twos-compliment value, while the second byte represents the low-order byte.每两个字节的数据可以组合成一个原始波形值。它的值是一个有符号的 16 位整数,范围从 -32768 到 32767。Value 的第一个字节表示二进制补码值的高位字节,而第二个字节代表低位字节。 To reconstruct the full raw wave value, simply shift the first byte left by 8 bits, and bitwise-or with the second byte.要重建完整的原始波形值,只需将第一个字节左移 8 位,然后按位或与第二个字节一起移动。

short raw = (Value[0]<<8) | Value[1];

One of the 2 bytes that I received is "ef".我收到的 2 个字节之一是“ef”。 When I used the bitwise operation above the result does not seems right as I noticed I never get a single negative value (its ECG data, negative values are normal).当我使用上面的按位运算时,结果似乎不正确,因为我注意到我从来没有得到一个负值(它的 ECG 数据,负值是正常的)。 I believe using Javascript to do this is not straight forward.我相信使用 Javascript 来做到这一点并不简单。 The way I did it was like this:我的做法是这样的:

var raw = "ef"; // just to show one. Actual one is an array of this 2 bytes but in string.
var value = raw.charAt(0) << 8 | raw.charAt(1)

Please Advice.请指教。 Thanks!谢谢!

EDIT:编辑:

I also did like this:我也这样做:

let first = new Int8Array(len); // len is the length of the raw data array
let second = new Int8Array(len);
let values = new Int16Array(len) // to hold the converted value

for(var i=0; i<len ; i++)
{
   //arr is the array that contains the every two "characters"
   first[i] = arr[i].charAt(0);
   second[i] = arr[i].charAt(1);
   values[i] = first[i] << 8 | second[i];  
}

But still all is positive result.但仍然是积极的结果。 no negative.没有负面。 Can someone verify if I am doing this correctly, just in case maybe the values are actually all positive :p有人可以验证我是否正确执行此操作,以防万一这些值实际上都是正数:p

It's two's complement: Check the top bit of the high byte - byte[high]>>7.它是二进制补码:检查高字节的最高位 - byte[high]>>7。 If it's 0, do byte[top]<<8 |如果为 0,则执行 byte[top]<<8 | byte[low].字节[低]。 If it is one, do -((byte[top]^0xff)<<8 | byte[low]^0xff) - 1. See https://en.wikipedia.org/wiki/Two%27s_complement for an explanation.如果是 1,请执行 -((byte[top]^0xff)<<8 | byte[low]^0xff) - 1。有关说明,请参阅https://en.wikipedia.org/wiki/Two%27s_complement

Also check out https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays .另请查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays It has Int16 arrays which is what you want.它有你想要的 Int16 数组。 It might be a ton faster.它可能会快一吨。

You can use property that the string is already 16 bit and then make it signed.您可以使用字符串已经是 16 位的属性,然后对其进行签名。
Also instead of reading 8bit at time just read one unsigned 16bit using charCodeAt.另外,不是一次读取 8 位,而是使用 charCodeAt 读取一个未签名的 16 位。

var raw = "\u00ef"; //original example
var buf = new Int16Array(1);
buf[0] = raw.charCodeAt(0); //now in the buf[0] is typed 16 bit integer
//returns 239, for \uffef returns -17

 var raw = "\￯"; //original example var buf = new Int16Array(1); buf[0] = raw.charCodeAt(0); //now in the buf[0] is typed 16 bit integer console.log(buf[0])

[EDIT] [编辑]

Use Int8Array to store byte data: 使用Int8Array存储字节数据:

function str2ua(str) {
    var buf = new Int8Array(str.length);
    for (var i = 0, strLen = str.length; i < strLen; i++) {
        buf[i] = str.charCodeAt(i);
    }
    return buf;
}

var raw = 'ef';
var buf = str2ua(raw);
var val = buf[0] << 8 | buf[1];
console.log(val);  // output 25958

raw = '¢f';
buf = str2ua(raw);
val = buf[0] << 8 | buf[1];
console.log(val);  // output -23962

For first byte take two's complement first then shift by 8 bit对于第一个字节,先取二进制补码,然后移位 8 位

let x = raw.charCodeAt(0); //ASCII value of first character

then flip x for 1's complement and add +1 for 2's complement and finally do然后翻转 x 为 1 的补码并添加 +1 为 2 的补码,最后做

var value = x << 8 | bytevalueof(raw.charCodeAt(1))

This is a question about the raw wave data coming from a Neurosky Mindwave Mobile EEG headset .这是一个关于来自 Neurosky Mindwave Mobile EEG 耳机原始波形数据的问题。

You should find three values in the buffer when you read from the device.从设备读取时,您应该在缓冲区中找到三个值。 Perform this operation on the second two to get a correct reading:对后两个执行此操作以获得正确读数:

    var b = reader.buffer(3);
    var raw = b[1]*256 + b[2];
    if(raw >= 32768) {
      raw = raw - 65536;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM