I am almost at the end of my rope on this one. I am attempting to parse out mp3 frame data, but I am having a bear of a time locating any frames. I am using Node 0.10 and trying to make use of the newer stream api (although it doesn't work with the old one either)
I am looping through the buffer looking for the 11 bit sync word, but i never find it.
var stream = fs.createReadStream('./myAudioFile.mp3')
stream.on('readable', function(data){
var chunk, header;
while (null !== (chunk = stream.read())) {
for (var i = 0; ( i + 4 ) <= chunk.length; i++) {
header = chunk.readUInt32LE(i)
if( (header & 0xFFE00000) === 0xFFE00000 ) {
//NEVER GET HERE!!!
}
}
}
Am i missing something here?
You're getting bitten by a quirk of Javascript bitwise operators. Let me demonstrate.
> 0xffffffff & 0xffe00000
-2097152
> 0xffe00000
4292870144
The result of a Javascript bitwise operation is always treated as a signed 32-bit integer. Since your constant is an unsigned 32-bit integer, it'll never match.
One potential fix is to use ~~
to perform the same mangling on your constant:
if ((header & 0xffe00000) == ~~0xffe00000) {
Another would be to just read in 16-bit integers instead, since the sync word will fit into that size anyway.
Unrelated but worth mentioning:
You're actually going to need to use chunk.readUInt32BE(i)
here, not LE. Right now you're finding instances of FE FF
in the stream, not FF FE
like you want.
In the rare instance that a sync word spans two chunks, your code misses it.