From 40e817dc526d1d41e900bb0f54d1a4451bda01ed Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Fri, 27 Jun 2014 21:58:26 +1000 Subject: [PATCH] src/flac/decode.c : Fix a cast-align warning from GCC. The old code was creating an array of FLAC__int8, and then casting that to a set of signed and unsigned 16 and 32 bit integers. This was replaced with a single union containing all the requred array. This solution means that there are fewer pointer casts and actually gives the compiler more information with which to generate fast code. --- src/flac/decode.c | 82 +++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/src/flac/decode.c b/src/flac/decode.c index 3f08c21d..771c36bc 100644 --- a/src/flac/decode.c +++ b/src/flac/decode.c @@ -966,12 +966,16 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder )); unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel; unsigned frame_bytes = 0; - static FLAC__int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; /* WATCHOUT: can be up to 2 megs */ - FLAC__uint8 *u8buffer = (FLAC__uint8 *)s8buffer; - FLAC__int16 *s16buffer = (FLAC__int16 *)s8buffer; - FLAC__uint16 *u16buffer = (FLAC__uint16 *)s8buffer; - FLAC__int32 *s32buffer = (FLAC__int32 *)s8buffer; - FLAC__uint32 *u32buffer = (FLAC__uint32 *)s8buffer; + + static union + { FLAC__int8 s8buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; /* WATCHOUT: can be up to 2 megs */ + FLAC__uint8 u8buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; + FLAC__int16 s16buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int16)]; + FLAC__uint16 u16buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int16)]; + FLAC__int32 s32buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS]; + FLAC__uint32 u32buffer [FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS]; + } ubuf; + size_t bytes_to_write = 0; (void)decoder; @@ -1092,7 +1096,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder } if(decoder_session->replaygain.apply) { bytes_to_write = FLAC__replaygain_synthesis__apply_gain( - u8buffer, + ubuf.u8buffer, !is_big_endian, is_unsigned_samples, buffer, @@ -1108,17 +1112,17 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder } /* first some special code for common cases */ else if(is_big_endian == is_big_endian_host_ && !is_unsigned_samples && channels == 2 && bps+shift == 16) { - FLAC__int16 *buf1_ = s16buffer + 1; + FLAC__int16 *buf1_ = ubuf.s16buffer + 1; if(is_big_endian) - memcpy(s16buffer, ((FLAC__byte*)(buffer[0]))+2, sizeof(FLAC__int32) * wide_samples - 2); + memcpy(ubuf.s16buffer, ((FLAC__byte*)(buffer[0]))+2, sizeof(FLAC__int32) * wide_samples - 2); else - memcpy(s16buffer, buffer[0], sizeof(FLAC__int32) * wide_samples); + memcpy(ubuf.s16buffer, buffer[0], sizeof(FLAC__int32) * wide_samples); for(sample = 0; sample < wide_samples; sample++, buf1_+=2) *buf1_ = (FLAC__int16)buffer[1][sample]; bytes_to_write = 4 * sample; } else if(is_big_endian == is_big_endian_host_ && !is_unsigned_samples && channels == 1 && bps+shift == 16) { - FLAC__int16 *buf1_ = s16buffer; + FLAC__int16 *buf1_ = ubuf.s16buffer; for(sample = 0; sample < wide_samples; sample++) *buf1_++ = (FLAC__int16)buffer[0][sample]; bytes_to_write = 2 * sample; @@ -1128,35 +1132,35 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder if(is_unsigned_samples) { if(channels == 2) { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) { - u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000); - u16buffer[sample++] = (FLAC__uint16)(buffer[1][wide_sample] + 0x8000); + ubuf.u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000); + ubuf.u16buffer[sample++] = (FLAC__uint16)(buffer[1][wide_sample] + 0x8000); } } else if(channels == 1) { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) - u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000); + ubuf.u16buffer[sample++] = (FLAC__uint16)(buffer[0][wide_sample] + 0x8000); } else { /* works for any 'channels' but above flavors are faster for 1 and 2 */ for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) for(channel = 0; channel < channels; channel++, sample++) - u16buffer[sample] = (FLAC__uint16)(buffer[channel][wide_sample] + 0x8000); + ubuf.u16buffer[sample] = (FLAC__uint16)(buffer[channel][wide_sample] + 0x8000); } } else { if(channels == 2) { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) { - s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]); - s16buffer[sample++] = (FLAC__int16)(buffer[1][wide_sample]); + ubuf.s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]); + ubuf.s16buffer[sample++] = (FLAC__int16)(buffer[1][wide_sample]); } } else if(channels == 1) { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) - s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]); + ubuf.s16buffer[sample++] = (FLAC__int16)(buffer[0][wide_sample]); } else { /* works for any 'channels' but above flavors are faster for 1 and 2 */ for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) for(channel = 0; channel < channels; channel++, sample++) - s16buffer[sample] = (FLAC__int16)(buffer[channel][wide_sample]); + ubuf.s16buffer[sample] = (FLAC__int16)(buffer[channel][wide_sample]); } } if(is_big_endian != is_big_endian_host_) { @@ -1164,9 +1168,9 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder const unsigned bytes = sample * 2; unsigned b; for(b = 0; b < bytes; b += 2) { - tmp = u8buffer[b]; - u8buffer[b] = u8buffer[b+1]; - u8buffer[b+1] = tmp; + tmp = ubuf.u8buffer[b]; + ubuf.u8buffer[b] = ubuf.u8buffer[b+1]; + ubuf.u8buffer[b+1] = tmp; } } bytes_to_write = 2 * sample; @@ -1175,24 +1179,24 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder if(is_unsigned_samples) { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) for(channel = 0; channel < channels; channel++, sample++) - u32buffer[sample] = buffer[channel][wide_sample] + 0x800000; + ubuf.u32buffer[sample] = buffer[channel][wide_sample] + 0x800000; } else { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) for(channel = 0; channel < channels; channel++, sample++) - s32buffer[sample] = buffer[channel][wide_sample]; + ubuf.s32buffer[sample] = buffer[channel][wide_sample]; } if(is_big_endian != is_big_endian_host_) { unsigned char tmp; const unsigned bytes = sample * 4; unsigned b; for(b = 0; b < bytes; b += 4) { - tmp = u8buffer[b]; - u8buffer[b] = u8buffer[b+3]; - u8buffer[b+3] = tmp; - tmp = u8buffer[b+1]; - u8buffer[b+1] = u8buffer[b+2]; - u8buffer[b+2] = tmp; + tmp = ubuf.u8buffer[b]; + ubuf.u8buffer[b] = ubuf.u8buffer[b+3]; + ubuf.u8buffer[b+3] = tmp; + tmp = ubuf.u8buffer[b+1]; + ubuf.u8buffer[b+1] = ubuf.u8buffer[b+2]; + ubuf.u8buffer[b+2] = tmp; } } if(is_big_endian) { @@ -1200,18 +1204,18 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder const unsigned bytes = sample * 4; for(lbyte = b = 0; b < bytes; ) { b++; - u8buffer[lbyte++] = u8buffer[b++]; - u8buffer[lbyte++] = u8buffer[b++]; - u8buffer[lbyte++] = u8buffer[b++]; + ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++]; + ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++]; + ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++]; } } else { unsigned b, lbyte; const unsigned bytes = sample * 4; for(lbyte = b = 0; b < bytes; ) { - u8buffer[lbyte++] = u8buffer[b++]; - u8buffer[lbyte++] = u8buffer[b++]; - u8buffer[lbyte++] = u8buffer[b++]; + ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++]; + ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++]; + ubuf.u8buffer[lbyte++] = ubuf.u8buffer[b++]; b++; } } @@ -1221,12 +1225,12 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder if(is_unsigned_samples) { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) for(channel = 0; channel < channels; channel++, sample++) - u8buffer[sample] = (FLAC__uint8)(buffer[channel][wide_sample] + 0x80); + ubuf.u8buffer[sample] = (FLAC__uint8)(buffer[channel][wide_sample] + 0x80); } else { for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++) for(channel = 0; channel < channels; channel++, sample++) - s8buffer[sample] = (FLAC__int8)(buffer[channel][wide_sample]); + ubuf.s8buffer[sample] = (FLAC__int8)(buffer[channel][wide_sample]); } bytes_to_write = sample; } @@ -1239,7 +1243,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder } } if(bytes_to_write > 0) { - if(flac__utils_fwrite(u8buffer, 1, bytes_to_write, fout) != bytes_to_write) { + if(flac__utils_fwrite(ubuf.u8buffer, 1, bytes_to_write, fout) != bytes_to_write) { /* if a pipe closed when writing to stdout, we let it go without an error message */ if(errno == EPIPE && decoder_session->fout == stdout) decoder_session->aborting_due_to_until = true;