The below code parses a sample pcm file
var dataFile = 'C:\\Users\\<user>\\Desktop\\small.pcm';
fs.readFile(dataFile, function(err, res) {
if(err) {
console.log('Error:', e.stack);
}else{
var ampData = [];
var arrByte = Uint8Array.from(Buffer.from(res)); //Convert to byte array
for(var i=0;i<arrByte.length;i=i+2){
var val;
var byteA = arrByte[i];
var byteB = arrByte[i+1];
var sign = byteA & (1 << 7);
var x = (((byteA & 0xFF) << 8) | (byteB & 0xFF)); // convert to 16 bit signed int
if (sign) { // if negative
val = 0xFFFF0000 | x; // fill in most significant bits with 1's
}else{
val = x;
}
ampData.push(val)
}
}
});
The pcm is single channel, signed 16bit, so its format is list of 2 byte. I want to know if this is the right way to extract raw amplitude data from the pcm file and store it in an array.
I need this to create a waveform graph of data values for the given length of the audio.
I got the reference to convert to signed 16 bit integer from here : Convert two bytes into signed 16 bit integer in JavaScript
Turns out that I needed to make it little endian byte ordering
for(var i=0;i<arrByte.length;i=i+2){
var byteA = arrByte[i];
var byteB = arrByte[i+1];
var sign = byteB & (1 << 7);
var val = (((byteA & 0xFF) | (byteB & 0xFF) << 8)); // convert to 16 bit signed int
if (sign) { // if negative
val = 0xFFFF0000 | val; // fill in most significant bits with 1's
}
ampData.push(val)
}
Now, I got the correct shape of the waveform as expected.
User contributions licensed under CC BY-SA 3.0