AC_DEFINE(FLAC__USE_3DNOW)
fi
+AC_ARG_ENABLE(altivec,
+[ --disable-altivec Disable Altivec optimizations],
+[case "${enableval}" in
+ yes) use_altivec=true ;;
+ no) use_altivec=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-altivec) ;;
+esac],[use_altivec=true])
+AM_CONDITIONAL(FLaC__USE_ALTIVEC, test x$use_altivec = xtrue)
+if test x$use_altivec = xtrue ; then
+AC_DEFINE(FLAC__USE_ALTIVEC)
+fi
+
AC_ARG_ENABLE(local-xmms-plugin,
[ --enable-local-xmms-plugin Install XMMS plugin to ~/.xmms/Plugins instead of system location],
[case "${enableval}" in
AH_TEMPLATE(FLAC__NO_ASM, [define to disable use of assembly code])
AH_TEMPLATE(FLAC__SSE_OS, [define if your operating system supports SSE instructions])
AH_TEMPLATE(FLAC__USE_3DNOW, [define to enable use of 3Dnow! instructions])
+AH_TEMPLATE(FLAC__USE_ALTIVEC, [define to enable use of Altivec instructions])
AH_TEMPLATE(ID3LIB_MAJOR, [define to major version number of id3lib])
AH_TEMPLATE(ID3LIB_MINOR, [define to minor version number of id3lib])
AH_TEMPLATE(ID3LIB_PATCH, [define to patch level of id3lib])
src/Makefile \
src/libFLAC/Makefile \
src/libFLAC/ia32/Makefile \
+ src/libFLAC/ppc/Makefile \
src/libFLAC/include/Makefile \
src/libFLAC/include/private/Makefile \
src/libFLAC/include/protected/Makefile \
#include <config.h>
#endif
+#if defined FLAC__CPU_PPC
+#if !defined FLAC__NO_ASM
+#if defined __APPLE__ && defined __MACH__
+#include <sys/sysctl.h>
+#endif /* __APPLE__ && __MACH__ */
+#endif /* FLAC__NO_ASM */
+#endif /* FLAC__CPU_PPC */
+
const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
#else
info->use_asm = false;
#endif
+#elif defined FLAC__CPU_PPC
+ info->type = FLAC__CPUINFO_TYPE_PPC;
+#if !defined FLAC__NO_ASM
+ info->use_asm = true;
+#ifdef FLAC__USE_ALTIVEC
+#if defined __APPLE__ && defined __MACH__
+ {
+ int selectors[2] = { CTL_HW, HW_VECTORUNIT };
+ int result = 0;
+ size_t length = sizeof(result);
+ int error = sysctl(selectors, 2, &result, &length, 0, 0);
+
+ info->data.ppc.altivec = error==0 ? result!=0 : 0;
+ }
+#else /* __APPLE__ && __MACH__ */
+ /* don't know of any other thread-safe way to check */
+ info->data.ppc.altivec = 0;
+#endif /* __APPLE__ && __MACH__ */
+#else /* FLAC__USE_ALTIVEC */
+ info->data.ppc.altivec = 0;
+#endif /* FLAC__USE_ALTIVEC */
+#else /* FLAC__NO_ASM */
+ info->use_asm = false;
+#endif /* FLAC__NO_ASM */
#else
info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
info->use_asm = false;
#include "private/fixed.h"
#include "private/format.h"
#include "private/lpc.h"
+#include "private/memory.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
FLAC__StreamDecoderWriteCallback write_callback;
FLAC__StreamDecoderMetadataCallback metadata_callback;
FLAC__StreamDecoderErrorCallback error_callback;
+ /* generic 32-bit datapath: */
void (*local_lpc_restore_signal)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
+ /* generic 64-bit datapath: */
void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
+ /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */
void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
+ /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */
+ void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
void *client_data;
FLAC__BitBuffer *input;
FLAC__int32 *output[FLAC__MAX_CHANNELS];
- FLAC__int32 *residual[FLAC__MAX_CHANNELS];
+ FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
unsigned output_capacity, output_channels;
FLAC__uint32 last_frame_number;
FLAC__CPUInfo cpuinfo;
FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */
FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
+ /* unaligned (original) pointers to allocated data */
+ FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS];
} FLAC__StreamDecoderPrivate;
/***********************************************************************
for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
decoder->private_->output[i] = 0;
- decoder->private_->residual[i] = 0;
+ decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
}
decoder->private_->output_capacity = 0;
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide;
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
+ decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal;
/* now override with asm where appropriate */
#ifndef FLAC__NO_ASM
if(decoder->private_->cpuinfo.use_asm) {
if(decoder->private_->cpuinfo.data.ia32.mmx) {
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
+ decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx;
}
else {
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
+ decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32;
}
#endif
+#elif defined FLAC__CPU_PPC
+ FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC);
+ if(decoder->private_->cpuinfo.data.ppc.altivec) {
+ decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16;
+ decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8;
+ }
#endif
}
#endif
free(decoder->private_->output[i]-4);
decoder->private_->output[i] = 0;
}
- if(0 != decoder->private_->residual[i]) {
- free(decoder->private_->residual[i]);
- decoder->private_->residual[i] = 0;
+ if(0 != decoder->private_->residual_unaligned[i]) {
+ free(decoder->private_->residual_unaligned[i]);
+ decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
}
}
decoder->private_->output_capacity = 0;
free(decoder->private_->output[i]-4);
decoder->private_->output[i] = 0;
}
- if(0 != decoder->private_->residual[i]) {
- free(decoder->private_->residual[i]);
- decoder->private_->residual[i] = 0;
+ if(0 != decoder->private_->residual_unaligned[i]) {
+ free(decoder->private_->residual_unaligned[i]);
+ decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
}
}
memset(tmp, 0, sizeof(FLAC__int32)*4);
decoder->private_->output[i] = tmp + 4;
- tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*size);
- if(tmp == 0) {
+ /* WATCHOUT:
+ * minimum of quadword alignment for PPC vector optimizations is REQUIRED:
+ */
+ if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
- decoder->private_->residual[i] = tmp;
}
decoder->private_->output_capacity = size;
if(do_full_decode) {
memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
- if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
- decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
+ if(bps <= 16 && subframe->qlp_coeff_precision <= 16) {
+ if(order <= 8)
+ decoder->private_->local_lpc_restore_signal_16bit_order8(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
+ else
+ decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
+ }
else
decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
else