12 Bit Input in C++
I'm trying to write a small application that enables 12-bit input and output. I have the output working, which by using 12 bits per word is able to write the numbers 4095 to 0 to a file. Essentially, the input is supposed to read that file (hence, read the numbers 4095 to 0). The input file has to have a 32-byte buffer (i.e. fill the buffer from the file, read in chunks of 12 bits, save the excess bits, refill buffer and repeat).
To test this, I have a loop that decreases 'i' from 4095 to 0. Inside the loop I request the 12Bit input class to give me the next 12bit number. Ideally, this should be equivalent to 'i'.
I believe I have the logic working, but for some reason the loop always fails once I get to 4078. The input class returns the value 3822 rather than the required 4078, despite it using the same logic and all numbers before that working as expected. I know it's not a problem reaching the end of the buffer (I haven't implemented that part yet), because this number is located from开发者_StackOverflow 25.5 - 27 bytes into the buffer. I have no idea why it is failing at this point.
Code for the input class:
int IStream12Bits::fetchCode()
{
byte data[2];
cout << "fByteCount: " << fByteCount << endl;
if(!(fByteCount % 3)){
cout << "!!! START OF BYTE !!!" << endl;
data[0] = fBuffer[fByteCount];
data[1] = (fBuffer[fByteCount + 1] & 0xF0);
fByteCount++;
}
else{
cout << "!!! MIDDLE OF BYTE !!!" << endl;
data[0] = fBuffer[fByteCount];
data[1] = fBuffer[(fByteCount + 1)];
data[0] = ((data[0] & 0x0F) << 4);
int temp = data[1];
temp = temp >> 4;
data[0] = (data[0] + temp);
data[1] = (data[1] & 0xF0);
fByteCount += 2;
}
int result = 0;
fByteIndex = 0;
fBitIndex = 8;
for(int i = 0; i < 12; i++){
if(data[fByteIndex] & (1 << (fBitIndex - 1))){ //if the MSB is 1, write it to the result
result += (1 << i);
}
fBitIndex--;
//if at the end of the byte, move on to the next
if(fBitIndex == 0){
fByteIndex = 1;
fBitIndex = 8;
}
}
return result;
}
EDIT:
All fixed. Problem was partly in the masking, and partly in my reading. All I had to do was read directly from fBuffer, because the algorithm was such that fBitIndex would be reduced to 4 after one read (causing the next read to automatically start halfway through a byte). No need to do masking and copying of data into a separate array. Turns out I was just making it more complex for myself.
Your code to "decode" the 12-bit values is much too complicated.
For the "even" case, you have the bits like this:
fBuffer[n] fBuffer[n+1] // var
76543210 76543210 // bit offsets
AAAAAAAA BBBB.... // value
And you need:
result
BA9876543210
AAAAAAAABBBB
Notice that the "A"s have been moved up by 4 positions, the "B"s move down by four. Translate that to C++:
result = (fBuffer[n] << 4) + ((fBuffer[n+1] & 0xF0)>>4);
For the "odd" case:
fBuffer[n] fBuffer[n+1]
76543210 76543210 // bit offsets
....AAAA BBBBBBBB
And you need:
result
BA9876543210
AAAABBBBBBBB
Notice that the "A"s have been moved up by 8 positions this time, and the "B"s don't need any shifting. Translate that to C++:
result = ((fBuffer[n] & 0x0F) << 8) + fBuffer[n+1];
That's all you need to decode the stream (assuming you're working with unsigned types).
There's something else that's fishy though: I'm not seeing calls reload
after the initial load. That is a problem.
Aha, hard to debug something like this!
data[1] = (data[1] & 0xF0)
I think this is supposed to say
data[1] = ((data[1] & 0x0F) << 4)
since you already used data[1] & 0xF0
in the previous line (as data[1] >> 4
).
精彩评论