Reputation: 63
I have a noob question about casting and shifting. I'm trying to store two elements of uint8_t
from an array as a single, signed element in an array of type int16_t
. However my result is not correct, and I' don't know why.
I have this code:
uint8_t buffer[BUFFER_SIZE];
int16_t mp3_stereo_buffer[BUFFER_SIZE];
for (i = 0; i < BUFFER_SIZE; i += 2) {
mp3_stereo_buffer[i] = ((uint16_t)buffer[i] << 8) | ((uint16_t)buffer[i + 1]);
}
Upvotes: 1
Views: 4962
Reputation: 94
#define LITTLE_ENDIAN
int main()
{
uint8_t buffer[4]={0x15,0xff,0x63,0xee};
int16_t mp3_stereo_buffer[2];
for (int i = 0; i < 2; i += 1) {
mp3_stereo_buffer[i] = ((int16_t*)buffer)[i];
#ifdef LITTLE_ENDIAN
mp3_stereo_buffer[i]=(mp3_stereo_buffer[i]>>8 &0x00ff) | (mp3_stereo_buffer[i]<<8 & 0xff00);
#endif
printf("%x\n",mp3_stereo_buffer[i]&0xffff);
}
return 0;
}
Upvotes: 0
Reputation: 85341
First, you can pack N uint8_t
into N/2 uint16_t
elements.
uint8_t buffer[BUFFER_SIZE];
uint16_t mp3_stereo_buffer[BUFFER_SIZE / 2];
Then you need to know if your data is little-endian or big-endian.
For little-endian:
for (i = 0; i < BUFFER_SIZE / 2; i++) {
mp3_stereo_buffer[i] = (uint16_t) (buffer[i*2] | (buffer[i*2+1] << 8));
}
For big-endian:
for (i = 0; i < BUFFER_SIZE / 2; i++) {
mp3_stereo_buffer[i] = (uint16_t) ((buffer[i*2] << 8) | buffer[i*2+1]);
}
p.s. If your data is in fact signed, then you can change the type and the casting to int16_t
but beware that the way signed numbers are represented is not guaranteed to be portable.
Upvotes: 1