1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Updated FLAC to version 1.3.1

This commit is contained in:
jules 2014-12-10 19:23:00 +00:00
parent 15ddb6699e
commit e090d569b7
47 changed files with 1461 additions and 820 deletions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* alloc - Convenience routines for safely allocating memory /* alloc - Convenience routines for safely allocating memory
* Copyright (C) 2007-2009 Josh Coalson * Copyright (C) 2007-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -33,7 +33,7 @@
#ifndef FLAC__SHARE__ALLOC_H #ifndef FLAC__SHARE__ALLOC_H
#define FLAC__SHARE__ALLOC_H #define FLAC__SHARE__ALLOC_H
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson * Copyright (C) 2004-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,5 +1,5 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2012 Xiph.org Foundation * Copyright (C) 2012-2014 Xiph.org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -73,23 +73,25 @@
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
#if _MSC_VER < 1500
/* Visual Studio 2008 has restrict. */
#define restrict __restrict
#endif
#define inline __inline #define inline __inline
#endif #endif
/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ #if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64)
#ifdef _MSC_VER /* MSVS generates VERY slow 32-bit code with __restrict */
#define FLAC__U64L(x) x #define flac_restrict __restrict
#elif defined __GNUC__
#define flac_restrict __restrict__
#else #else
#define FLAC__U64L(x) x##LLU #define flac_restrict
#endif #endif
#define FLAC__U64L(x) x##ULL
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
#define FLAC__STRCASECMP stricmp
#define FLAC__STRNCASECMP strnicmp #define FLAC__STRNCASECMP strnicmp
#else #else
#define FLAC__STRCASECMP strcasecmp
#define FLAC__STRNCASECMP strncasecmp #define FLAC__STRNCASECMP strncasecmp
#endif #endif
@ -139,6 +141,7 @@
#ifdef _WIN32 #ifdef _WIN32
/* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */ /* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */
#include "win_utf8_io.h"
#define flac_printf printf_utf8 #define flac_printf printf_utf8
#define flac_fprintf fprintf_utf8 #define flac_fprintf fprintf_utf8
@ -160,12 +163,7 @@
#define flac_utime utime #define flac_utime utime
#define flac_unlink unlink #define flac_unlink unlink
#define flac_rename rename #define flac_rename rename
#ifdef _WIN32
#define flac_stat _stat64
#else
#define flac_stat stat #define flac_stat stat
#endif
#endif #endif
@ -177,8 +175,14 @@
#define flac_fstat fstat #define flac_fstat fstat
#endif #endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530942
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
/* FLAC needs to compile and work correctly on systems with a norrmal ISO C99 /* FLAC needs to compile and work correctly on systems with a normal ISO C99
* snprintf as well as Microsoft Visual Studio which has an non-standards * snprintf as well as Microsoft Visual Studio which has an non-standards
* conformant snprint_s function. * conformant snprint_s function.
* *
@ -188,6 +192,7 @@
extern "C" { extern "C" {
#endif #endif
int flac_snprintf(char *str, size_t size, const char *fmt, ...); int flac_snprintf(char *str, size_t size, const char *fmt, ...);
int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va);
#ifdef __cplusplus #ifdef __cplusplus
}; };
#endif #endif

View file

@ -1,5 +1,5 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2012 Xiph.org Foundation * Copyright (C) 2012-2014 Xiph.org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -33,20 +33,46 @@
#if HAVE_BSWAP32 /* GCC and Clang */ #if HAVE_BSWAP32 /* GCC and Clang */
/* GCC prior to 4.8 didn't provide bswap16 on x86_64 */
#if ! HAVE_BSWAP16
static inline unsigned short __builtin_bswap16(unsigned short a)
{
return (a<<8)|(a>>8);
}
#endif
#define ENDSWAP_16(x) (__builtin_bswap16 (x))
#define ENDSWAP_32(x) (__builtin_bswap32 (x)) #define ENDSWAP_32(x) (__builtin_bswap32 (x))
#elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */ #elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */
#define ENDSWAP_16(x) (_byteswap_ushort (x))
#define ENDSWAP_32(x) (_byteswap_ulong (x)) #define ENDSWAP_32(x) (_byteswap_ulong (x))
#elif defined HAVE_BYTESWAP_H /* Linux */ #elif defined HAVE_BYTESWAP_H /* Linux */
#include <byteswap.h> #include <byteswap.h>
#define ENDSWAP_16(x) (bswap_16 (x))
#define ENDSWAP_32(x) (bswap_32 (x)) #define ENDSWAP_32(x) (bswap_32 (x))
#else #else
#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24)) #define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24))
#endif
/* Host to little-endian byte swapping. */
#if CPU_IS_BIG_ENDIAN
#define H2LE_16(x) ENDSWAP_16 (x)
#define H2LE_32(x) ENDSWAP_32 (x)
#else
#define H2LE_16(x) (x)
#define H2LE_32(x) (x)
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -61,9 +61,9 @@
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#ifdef FLAC_API_EXPORTS #ifdef FLAC_API_EXPORTS
#define FLAC_API _declspec(dllexport) #define FLAC_API __declspec(dllexport)
#else #else
#define FLAC_API _declspec(dllimport) #define FLAC_API __declspec(dllimport)
#endif #endif
#elif defined(FLAC__USE_VISIBILITY_ATTR) #elif defined(FLAC__USE_VISIBILITY_ATTR)

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -509,9 +509,11 @@ typedef enum {
FLAC__METADATA_TYPE_PICTURE = 6, FLAC__METADATA_TYPE_PICTURE = 6,
/**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */ /**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */
FLAC__METADATA_TYPE_UNDEFINED = 7 FLAC__METADATA_TYPE_UNDEFINED = 7,
/**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */
FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE,
/**< No type will ever be greater than this. There is not enough room in the protocol block. */
} FLAC__MetadataType; } FLAC__MetadataType;
/** Maps a FLAC__MetadataType to a C string. /** Maps a FLAC__MetadataType to a C string.

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,12 +30,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include "include/private/bitmath.h" #include "include/private/bitmath.h"
#include "../assert.h"
/* An example of what FLAC__bitmath_silog2() computes: /* An example of what FLAC__bitmath_silog2() computes:
* *

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -73,7 +73,6 @@
*/ */
static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */ static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */
/* WATCHOUT: assembly routines rely on the order in which these fields are declared */
struct FLAC__BitReader { struct FLAC__BitReader {
/* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */
/* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */ /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */
@ -87,7 +86,6 @@ struct FLAC__BitReader {
unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */ unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
FLAC__BitReaderReadCallback read_callback; FLAC__BitReaderReadCallback read_callback;
void *client_data; void *client_data;
FLAC__CPUInfo cpu_info;
}; };
static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word) static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word)
@ -119,8 +117,7 @@ static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word)
br->crc16_align = 0; br->crc16_align = 0;
} }
/* would be static except it needs to be called by asm routines */ static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
{ {
unsigned start, end; unsigned start, end;
size_t bytes; size_t bytes;
@ -231,7 +228,7 @@ void FLAC__bitreader_delete(FLAC__BitReader *br)
* *
***********************************************************************/ ***********************************************************************/
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd) FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd)
{ {
FLAC__ASSERT(0 != br); FLAC__ASSERT(0 != br);
@ -243,7 +240,6 @@ FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__Bi
return false; return false;
br->read_callback = rcb; br->read_callback = rcb;
br->client_data = cd; br->client_data = cd;
br->cpu_info = cpu;
return true; return true;
} }
@ -1048,9 +1044,9 @@ FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *v
return true; return true;
} }
/* These functions a declared inline in this file but are also callable as /* These functions are declared inline in this file but are also callable as
* externs from elsewhere. * externs from elsewhere.
* According to the C99 sepc, section 6.7.4, simply providing a function * According to the C99 spec, section 6.7.4, simply providing a function
* prototype in a header file without 'inline' and making the function inline * prototype in a header file without 'inline' and making the function inline
* in this file should be sufficient. * in this file should be sufficient.
* Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -47,8 +47,7 @@
/* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */ /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */
/* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */ /* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */
#define FLAC__BYTES_PER_WORD 4 #define FLAC__BYTES_PER_WORD 4
#undef FLAC__BITS_PER_WORD #define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD)
#define FLAC__BITS_PER_WORD 32
#define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff)
/* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */ /* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
@ -524,28 +523,6 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL
msbits = uval >> parameter; msbits = uval >> parameter;
#if 0 /* OPT: can remove this special case if it doesn't make up for the extra compare (doesn't make a statistically significant difference with msvc or gcc/x86) */
if(bw->bits && bw->bits + msbits + lsbits <= FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */
/* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */
bw->bits = bw->bits + msbits + lsbits;
uval |= mask1; /* set stop bit */
uval &= mask2; /* mask off unused top bits */
/* NOT: bw->accum <<= msbits + lsbits because msbits+lsbits could be 32, then the shift would be a NOP */
bw->accum <<= msbits;
bw->accum <<= lsbits;
bw->accum |= uval;
if(bw->bits == FLAC__BITS_PER_WORD) {
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
bw->bits = 0;
/* burying the capacity check down here means we have to grow the buffer a little if there are more vals to do */
if(bw->capacity <= bw->words && nvals > 1 && !bitwriter_grow_(bw, 1)) {
FLAC__ASSERT(bw->capacity == bw->words);
return false;
}
}
}
else {
#elif 1 /*@@@@@@ OPT: try this version with MSVC6 to see if better, not much difference for gcc-4 */
if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */ if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */
/* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */ /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */
bw->bits = bw->bits + msbits + lsbits; bw->bits = bw->bits + msbits + lsbits;
@ -555,7 +532,6 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL
bw->accum |= uval; bw->accum |= uval;
} }
else { else {
#endif
/* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
/* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */ /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */
if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 uint32_t*/ && !bitwriter_grow_(bw, msbits+lsbits)) if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 uint32_t*/ && !bitwriter_grow_(bw, msbits+lsbits))
@ -610,9 +586,7 @@ break1:
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
bw->accum = uval; bw->accum = uval;
} }
#if 1
} }
#endif
vals++; vals++;
nvals--; nvals--;
} }
@ -853,9 +827,9 @@ FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw)
return true; return true;
} }
/* These functions a declared inline in this file but are also callable as /* These functions are declared inline in this file but are also callable as
* externs from elsewhere. * externs from elsewhere.
* According to the C99 sepc, section 6.7.4, simply providing a function * According to the C99 spec, section 6.7.4, simply providing a function
* prototype in a header file without 'inline' and making the function inline * prototype in a header file without 'inline' and making the function inline
* in this file should be sufficient. * in this file should be sufficient.
* Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,47 +30,47 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include "include/private/cpu.h" #include "include/private/cpu.h"
#include <stdlib.h>
#include <stdio.h> #if 0
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#endif
#if defined FLAC__CPU_IA32 #if defined FLAC__CPU_IA32
# include <signal.h> # include <signal.h>
#elif defined FLAC__CPU_PPC
# if !defined FLAC__NO_ASM
# if defined FLAC__SYS_DARWIN
# include <sys/sysctl.h>
# include <mach/mach.h>
# include <mach/mach_host.h>
# include <mach/host_info.h>
# include <mach/machine.h>
# ifndef CPU_SUBTYPE_POWERPC_970
# define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
# endif
# else /* FLAC__SYS_DARWIN */
# include <signal.h> static void disable_sse(FLAC__CPUInfo *info)
# include <setjmp.h>
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump = 0;
static void sigill_handler (int sig)
{ {
if (!canjump) { info->ia32.sse = false;
signal (sig, SIG_DFL); info->ia32.sse2 = false;
raise (sig); info->ia32.sse3 = false;
} info->ia32.ssse3 = false;
canjump = 0; info->ia32.sse41 = false;
siglongjmp (jmpbuf, 1); info->ia32.sse42 = false;
} }
# endif /* FLAC__SYS_DARWIN */
# endif /* FLAC__NO_ASM */ static void disable_avx(FLAC__CPUInfo *info)
#endif /* FLAC__CPU_PPC */ {
info->ia32.avx = false;
info->ia32.avx2 = false;
info->ia32.fma = false;
}
#elif defined FLAC__CPU_X86_64
static void disable_avx(FLAC__CPUInfo *info)
{
info->x86.avx = false;
info->x86.avx2 = false;
info->x86.fma = false;
}
#endif
#if defined (__NetBSD__) || defined(__OpenBSD__) #if defined (__NetBSD__) || defined(__OpenBSD__)
#include <sys/param.h> #include <sys/param.h>
@ -87,25 +87,34 @@ static void sigill_handler (int sig)
/* how to get sysctlbyname()? */ /* how to get sysctlbyname()? */
#endif #endif
#ifdef FLAC__CPU_IA32
/* these are flags in EDX of CPUID AX=00000001 */ /* these are flags in EDX of CPUID AX=00000001 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
#endif
/* these are flags in ECX of CPUID AX=00000001 */ /* these are flags in ECX of CPUID AX=00000001 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200;
/* these are flags in EDX of CPUID AX=80000001 */ static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
#if defined FLAC__AVX_SUPPORTED
/* these are flags in ECX of CPUID AX=00000001 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000;
/* these are flags in EBX of CPUID AX=00000007 */
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020;
#endif
/* /*
* Extra stuff needed for detection of OS support for SSE on IA-32 * Extra stuff needed for detection of OS support for SSE on IA-32
*/ */
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS
# if defined(__linux__) # if defined(__linux__)
/* /*
* If the OS doesn't support SSE, we will get here with a SIGILL. We * If the OS doesn't support SSE, we will get here with a SIGILL. We
@ -120,35 +129,14 @@ static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
* 6 bytes extra in case our estimate is wrong * 6 bytes extra in case our estimate is wrong
* 12 bytes puts us in the NOP "landing zone" * 12 bytes puts us in the NOP "landing zone"
*/ */
# undef USE_OBSOLETE_SIGCONTEXT_FLAVOR /* #define this to use the older signal handler method */
# ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR
static void sigill_handler_sse_os(int signal, struct sigcontext sc)
{
(void)signal;
sc.eip += 3 + 3 + 6;
}
# else
# include <sys/ucontext.h> # include <sys/ucontext.h>
static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc) static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc)
{ {
(void)signal, (void)si; (void)signal, (void)si;
((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6; ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6;
} }
# endif
# elif defined(_MSC_VER) # elif defined(_MSC_VER)
# include <windows.h> # include <windows.h>
# define USE_TRY_CATCH_FLAVOR /* sigill_handler flavor resulted in several crash reports on win32 */
# ifdef USE_TRY_CATCH_FLAVOR
# else
LONG CALLBACK sigill_handler_sse_os(EXCEPTION_POINTERS *ep)
{
if(ep->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) {
ep->ContextRecord->Eip += 3 + 3 + 6;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
# endif
# endif # endif
#endif #endif
@ -159,261 +147,344 @@ void FLAC__cpu_info(FLAC__CPUInfo *info)
* IA32-specific * IA32-specific
*/ */
#ifdef FLAC__CPU_IA32 #ifdef FLAC__CPU_IA32
FLAC__bool ia32_fxsr = false;
FLAC__bool ia32_osxsave = false;
(void) ia32_fxsr; (void) ia32_osxsave; /* to avoid warnings about unused variables */
memset(info, 0, sizeof(*info));
info->type = FLAC__CPUINFO_TYPE_IA32; info->type = FLAC__CPUINFO_TYPE_IA32;
#if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM #if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN)
info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */ info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */
info->data.ia32.cpuid = FLAC__cpu_have_cpuid_asm_ia32()? true : false; #ifdef FLAC__HAS_X86INTRIN
info->data.ia32.bswap = info->data.ia32.cpuid; /* CPUID => BSWAP since it came after */ if(!FLAC__cpu_have_cpuid_x86())
info->data.ia32.cmov = false; return;
info->data.ia32.mmx = false;
info->data.ia32.fxsr = false;
info->data.ia32.sse = false;
info->data.ia32.sse2 = false;
info->data.ia32.sse3 = false;
info->data.ia32.ssse3 = false;
info->data.ia32._3dnow = false;
info->data.ia32.ext3dnow = false;
info->data.ia32.extmmx = false;
if(info->data.ia32.cpuid) {
/* http://www.sandpile.org/ia32/cpuid.htm */
FLAC__uint32 flags_edx, flags_ecx;
FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
info->data.ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false;
info->data.ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false;
info->data.ia32.fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false;
info->data.ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false;
info->data.ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false;
info->data.ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
info->data.ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
#ifdef FLAC__USE_3DNOW
flags_edx = FLAC__cpu_info_extended_amd_asm_ia32();
info->data.ia32._3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW )? true : false;
info->data.ia32.ext3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false;
info->data.ia32.extmmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX )? true : false;
#else #else
info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false; if(!FLAC__cpu_have_cpuid_asm_ia32())
return;
#endif #endif
{
/* http://www.sandpile.org/x86/cpuid.htm */
#ifdef FLAC__HAS_X86INTRIN
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
#else
FLAC__uint32 flags_ecx, flags_edx;
FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
#endif
info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false;
info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false;
ia32_fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false;
info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false;
info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false;
info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
#if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false;
info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false;
info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false;
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false;
#endif
}
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "CPU info (IA-32):\n"); fprintf(stderr, "CPU info (IA-32):\n");
fprintf(stderr, " CPUID ...... %c\n", info->data.ia32.cpuid ? 'Y' : 'n'); fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
fprintf(stderr, " BSWAP ...... %c\n", info->data.ia32.bswap ? 'Y' : 'n'); fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
fprintf(stderr, " CMOV ....... %c\n", info->data.ia32.cmov ? 'Y' : 'n'); fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
fprintf(stderr, " MMX ........ %c\n", info->data.ia32.mmx ? 'Y' : 'n'); fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
fprintf(stderr, " FXSR ....... %c\n", info->data.ia32.fxsr ? 'Y' : 'n'); fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSE ........ %c\n", info->data.ia32.sse ? 'Y' : 'n'); fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
fprintf(stderr, " SSE2 ....... %c\n", info->data.ia32.sse2 ? 'Y' : 'n'); fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
fprintf(stderr, " SSE3 ....... %c\n", info->data.ia32.sse3 ? 'Y' : 'n'); fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->data.ia32.ssse3 ? 'Y' : 'n'); # if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
fprintf(stderr, " 3DNow! ..... %c\n", info->data.ia32._3dnow ? 'Y' : 'n'); fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
fprintf(stderr, " 3DNow!-ext . %c\n", info->data.ia32.ext3dnow? 'Y' : 'n'); fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
fprintf(stderr, " 3DNow!-MMX . %c\n", info->data.ia32.extmmx ? 'Y' : 'n'); fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
# endif
#endif #endif
/* /*
* now have to check for OS support of SSE/SSE2 * now have to check for OS support of SSE instructions
*/ */
if(info->data.ia32.fxsr || info->data.ia32.sse || info->data.ia32.sse2) { if(info->ia32.sse) {
#if defined FLAC__NO_SSE_OS #if defined FLAC__NO_SSE_OS
/* assume user knows better than us; turn it off */ /* assume user knows better than us; turn it off */
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; disable_sse(info);
#elif defined FLAC__SSE_OS #elif defined FLAC__SSE_OS
/* assume user knows better than us; leave as detected above */ /* assume user knows better than us; leave as detected above */
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__) #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__)
int sse = 0; int sse = 0;
size_t len; size_t len;
/* at least one of these must work: */ /* at least one of these must work: */
len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse); len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse);
len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */ len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */
if(!sse) if(!sse)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; disable_sse(info);
#elif defined(__NetBSD__) || defined (__OpenBSD__) #elif defined(__NetBSD__) || defined (__OpenBSD__)
# if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__) # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__)
int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE }; int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE };
size_t len = sizeof(val); size_t len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; disable_sse(info);
else { /* double-check SSE2 */ else { /* double-check SSE2 */
mib[1] = CPU_SSE2; mib[1] = CPU_SSE2;
len = sizeof(val); len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) {
info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; disable_sse(info);
info->ia32.sse = true;
} }
}
# else # else
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; disable_sse(info);
# endif # endif
#elif defined(__linux__) #elif defined(__linux__)
int sse = 0; int sse = 0;
struct sigaction sigill_save; struct sigaction sigill_save;
#ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR struct sigaction sigill_sse;
if(0 == sigaction(SIGILL, NULL, &sigill_save) && signal(SIGILL, (void (*)(int))sigill_handler_sse_os) != SIG_ERR) sigill_sse.sa_sigaction = sigill_handler_sse_os;
#else __sigemptyset(&sigill_sse.sa_mask);
struct sigaction sigill_sse; sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */
sigill_sse.sa_sigaction = sigill_handler_sse_os; if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save))
__sigemptyset(&sigill_sse.sa_mask); {
sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */ /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */
if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save)) /* see sigill_handler_sse_os() for an explanation of the following: */
#endif
{
/* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */
/* see sigill_handler_sse_os() for an explanation of the following: */
asm volatile (
"xorl %0,%0\n\t" /* for some reason, still need to do this to clear 'sse' var */
"xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */
"incl %0\n\t" /* SIGILL handler will jump over this */
/* landing zone */
"nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */
"nop\n\t"
"nop" /* SIGILL jump lands here if "inc" is 1 byte */
: "=r"(sse)
: "r"(sse)
);
sigaction(SIGILL, &sigill_save, NULL);
}
if(!sse)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
#elif defined(_MSC_VER)
# ifdef USE_TRY_CATCH_FLAVOR
_try {
__asm {
# if _MSC_VER <= 1200
/* VC6 assembler doesn't know SSE, have to emit bytecode instead */
_emit 0x0F
_emit 0x57
_emit 0xC0
# else
xorps xmm0,xmm0
# endif
}
}
_except(EXCEPTION_EXECUTE_HANDLER) {
if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
}
# else
int sse = 0;
LPTOP_LEVEL_EXCEPTION_FILTER save = SetUnhandledExceptionFilter(sigill_handler_sse_os);
/* see GCC version above for explanation */
/* http://msdn2.microsoft.com/en-us/library/4ks26t93.aspx */
/* http://www.codeproject.com/cpp/gccasm.asp */
/* http://www.hick.org/~mmiller/msvc_inline_asm.html */
__asm {
# if _MSC_VER <= 1200
/* VC6 assembler doesn't know SSE, have to emit bytecode instead */
_emit 0x0F
_emit 0x57
_emit 0xC0
# else
xorps xmm0,xmm0
# endif
inc sse
nop
nop
nop
nop
nop
nop
nop
nop
nop
}
SetUnhandledExceptionFilter(save);
if(!sse)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
# endif
#else
/* no way to test, disable to be safe */
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
#endif
#ifdef DEBUG
fprintf(stderr, " SSE OS sup . %c\n", info->data.ia32.sse ? 'Y' : 'n');
#endif
}
}
#else
info->use_asm = false;
#endif
/*
* PPC-specific
*/
#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 FLAC__SYS_DARWIN
{
int val = 0, mib[2] = { CTL_HW, HW_VECTORUNIT };
size_t len = sizeof(val);
info->data.ppc.altivec = !(sysctl(mib, 2, &val, &len, NULL, 0) || !val);
}
{
host_basic_info_data_t hostInfo;
mach_msg_type_number_t infoCount;
infoCount = HOST_BASIC_INFO_COUNT;
host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970);
}
# else /* FLAC__USE_ALTIVEC && !FLAC__SYS_DARWIN */
{
/* no Darwin, do it the brute-force way */
/* @@@@@@ this is not thread-safe; replace with SSE OS method above or remove */
info->data.ppc.altivec = 0;
info->data.ppc.ppc64 = 0;
signal (SIGILL, sigill_handler);
canjump = 0;
if (!sigsetjmp (jmpbuf, 1)) {
canjump = 1;
asm volatile ( asm volatile (
"mtspr 256, %0\n\t" "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */
"vand %%v0, %%v0, %%v0" "incl %0\n\t" /* SIGILL handler will jump over this */
: /* landing zone */
: "r" (-1) "nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */
"nop\n\t"
"nop" /* SIGILL jump lands here if "inc" is 1 byte */
: "=r"(sse)
: "0"(sse)
); );
info->data.ppc.altivec = 1; sigaction(SIGILL, &sigill_save, NULL);
} }
canjump = 0;
if (!sigsetjmp (jmpbuf, 1)) {
int x = 0;
canjump = 1;
/* PPC64 hardware implements the cntlzd instruction */ if(!sse)
asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) ); disable_sse(info);
#elif defined(_MSC_VER)
info->data.ppc.ppc64 = 1; __try {
__asm {
xorps xmm0,xmm0
}
} }
signal (SIGILL, SIG_DFL); /*@@@@@@ should save and restore old signal */ __except(EXCEPTION_EXECUTE_HANDLER) {
if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
disable_sse(info);
}
#elif defined(__GNUC__) /* MinGW goes here */
int sse = 0;
/* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */
/* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) */
if (ia32_fxsr) {
struct {
FLAC__uint32 buff[128];
} __attribute__((aligned(16))) fxsr;
FLAC__uint32 old_val, new_val;
asm volatile ("fxsave %0" : "=m" (fxsr) : "m" (fxsr));
old_val = fxsr.buff[50];
fxsr.buff[50] ^= 0x0013c0de; /* change value in the buffer */
asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* try to change SSE register */
fxsr.buff[50] = old_val; /* restore old value in the buffer */
asm volatile ("fxsave %0 " : "=m" (fxsr) : "m" (fxsr)); /* old value will be overwritten if SSE register was changed */
new_val = fxsr.buff[50]; /* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */
fxsr.buff[50] = old_val; /* again restore old value in the buffer */
asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* restore old values of registers */
if ((old_val^new_val) == 0x0013c0de)
sse = 1;
}
if(!sse)
disable_sse(info);
#else
/* no way to test, disable to be safe */
disable_sse(info);
#endif
#ifdef DEBUG
fprintf(stderr, " SSE OS sup . %c\n", info->ia32.sse ? 'Y' : 'n');
#endif
} }
# endif else /* info->ia32.sse == false */
# else /* !FLAC__USE_ALTIVEC */ disable_sse(info);
info->data.ppc.altivec = 0;
info->data.ppc.ppc64 = 0; /*
# endif * now have to check for OS support of AVX instructions
# else */
if(info->ia32.avx && ia32_osxsave) {
FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
if ((ecr & 0x6) != 0x6)
disable_avx(info);
#ifdef DEBUG
fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n');
#endif
}
else /* no OS AVX support*/
disable_avx(info);
#else
info->use_asm = false; info->use_asm = false;
# endif #endif
/* /*
* unknown CPI * x86-64-specific
*/
#elif defined FLAC__CPU_X86_64
FLAC__bool x86_osxsave = false;
(void) x86_osxsave; /* to avoid warnings about unused variables */
memset(info, 0, sizeof(*info));
info->type = FLAC__CPUINFO_TYPE_X86_64;
#if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN
info->use_asm = true;
{
/* http://www.sandpile.org/x86/cpuid.htm */
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
#if defined FLAC__AVX_SUPPORTED
x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false;
info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false;
info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false;
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false;
#endif
}
#ifdef DEBUG
fprintf(stderr, "CPU info (x86-64):\n");
fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
# if defined FLAC__AVX_SUPPORTED
fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n');
fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n');
fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n');
# endif
#endif
/*
* now have to check for OS support of AVX instructions
*/
if(info->x86.avx && x86_osxsave) {
FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
if ((ecr & 0x6) != 0x6)
disable_avx(info);
#ifdef DEBUG
fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
#endif
}
else /* no OS AVX support*/
disable_avx(info);
#else
info->use_asm = false;
#endif
/*
* unknown CPU
*/ */
#else #else
info->type = FLAC__CPUINFO_TYPE_UNKNOWN; info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
info->use_asm = false; info->use_asm = false;
#endif #endif
} }
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#if defined _MSC_VER
#include <intrin.h> /* for __cpuid() and _xgetbv() */
#elif defined __GNUC__ && defined HAVE_CPUID_H
#include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */
#endif
FLAC__uint32 FLAC__cpu_have_cpuid_x86(void)
{
#ifdef FLAC__CPU_X86_64
return 1;
#else
# if defined _MSC_VER || defined __INTEL_COMPILER /* Do they support CPUs w/o CPUID support (or OSes that work on those CPUs)? */
FLAC__uint32 flags1, flags2;
__asm {
pushfd
pushfd
pop eax
mov flags1, eax
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
mov flags2, eax
popfd
}
if (((flags1^flags2) & 0x200000) != 0)
return 1;
else
return 0;
# elif defined __GNUC__ && defined HAVE_CPUID_H
if (__get_cpuid_max(0, 0) != 0)
return 1;
else
return 0;
# else
return 0;
# endif
#endif
}
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx)
{
(void) level;
#if defined _MSC_VER || defined __INTEL_COMPILER
int cpuinfo[4];
int ext = level & 0x80000000;
__cpuid(cpuinfo, ext);
if((unsigned)cpuinfo[0] < level) {
*eax = *ebx = *ecx = *edx = 0;
return;
}
#if defined FLAC__AVX_SUPPORTED
__cpuidex(cpuinfo, level, 0); /* for AVX2 detection */
#else
__cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */
#endif
*eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3];
#elif defined __GNUC__ && defined HAVE_CPUID_H
FLAC__uint32 ext = level & 0x80000000;
__cpuid(ext, *eax, *ebx, *ecx, *edx);
if (*eax < level) {
*eax = *ebx = *ecx = *edx = 0;
return;
}
__cpuid_count(level, 0, *eax, *ebx, *ecx, *edx);
#else
*eax = *ebx = *ecx = *edx = 0;
#endif
}
FLAC__uint32 FLAC__cpu_xgetbv_x86(void)
{
#if (defined _MSC_VER || defined __INTEL_COMPILER) && defined FLAC__AVX_SUPPORTED
return (FLAC__uint32)_xgetbv(0);
#elif defined __GNUC__
FLAC__uint32 lo, hi;
asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0));
return lo;
#else
return 0;
#endif
}
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,21 +30,17 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include "../compat.h"
#include "include/private/bitmath.h" #include "include/private/bitmath.h"
#include "include/private/fixed.h" #include "include/private/fixed.h"
#include "../assert.h" #include "../assert.h"
#ifndef M_LN2
/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
#define M_LN2 0.69314718055994530942
#endif
#ifdef local_abs #ifdef local_abs
#undef local_abs #undef local_abs
#endif #endif
@ -320,20 +316,11 @@ unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsig
FLAC__ASSERT(data_len > 0 || total_error_3 == 0); FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
FLAC__ASSERT(data_len > 0 || total_error_4 == 0); FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#if defined _MSC_VER || defined __MINGW32__
/* with MSVC you have to spoon feed it the casting */
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
#else
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
#endif
#else #else
residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0;
residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0;

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson * Copyright (C) 2004-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -45,12 +45,7 @@
/* VERSION should come from configure */ /* VERSION should come from configure */
FLAC_API const char *FLAC__VERSION_STRING = VERSION; FLAC_API const char *FLAC__VERSION_STRING = VERSION;
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125";
/* yet one more hack because of MSVC6: */
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.3.0 20130526";
#else
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20130526";
#endif
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -34,6 +34,7 @@
#define FLAC__PRIVATE__BITMATH_H #define FLAC__PRIVATE__BITMATH_H
#include "../../../ordinals.h" #include "../../../ordinals.h"
#include "../../../assert.h"
/* for CHAR_BIT */ /* for CHAR_BIT */
#include <limits.h> #include <limits.h>
@ -74,16 +75,19 @@ static inline unsigned int FLAC__clz_soft_uint32(unsigned int word)
static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v) static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v)
{ {
/* Never used with input 0 */ /* Never used with input 0 */
FLAC__ASSERT(v > 0);
#if defined(__INTEL_COMPILER) #if defined(__INTEL_COMPILER)
return _bit_scan_reverse(v) ^ 31U; return _bit_scan_reverse(v) ^ 31U;
#elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
/* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on /* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on
* -march= setting or to a software rutine in exotic machines. */ * -march= setting or to a software routine in exotic machines. */
return __builtin_clz(v); return __builtin_clz(v);
#elif defined(_MSC_VER) && (_MSC_VER >= 1400) #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
FLAC__uint32 idx; {
_BitScanReverse((DWORD*) &idx, v); unsigned long idx;
return idx ^ 31U; _BitScanReverse(&idx, v);
return idx ^ 31U;
}
#else #else
return FLAC__clz_soft_uint32(v); return FLAC__clz_soft_uint32(v);
#endif #endif
@ -99,7 +103,7 @@ static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v)
/* An example of what FLAC__bitmath_ilog2() computes: /* An example of what FLAC__bitmath_ilog2() computes:
* *
* ilog2( 0) = undefined * ilog2( 0) = assertion failure
* ilog2( 1) = 0 * ilog2( 1) = 0
* ilog2( 2) = 1 * ilog2( 2) = 1
* ilog2( 3) = 1 * ilog2( 3) = 1
@ -122,45 +126,56 @@ static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v)
static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v) static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
{ {
FLAC__ASSERT(v > 0);
#if defined(__INTEL_COMPILER)
return _bit_scan_reverse(v);
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
{
unsigned long idx;
_BitScanReverse(&idx, v);
return idx;
}
#else
return sizeof(FLAC__uint32) * CHAR_BIT - 1 - FLAC__clz_uint32(v); return sizeof(FLAC__uint32) * CHAR_BIT - 1 - FLAC__clz_uint32(v);
#endif
} }
#ifdef FLAC__INTEGER_ONLY_LIBRARY /*Unused otherwise */ #ifdef FLAC__INTEGER_ONLY_LIBRARY /* Unused otherwise */
static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v) static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
{ {
if (v == 0) FLAC__ASSERT(v > 0);
return 0;
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v); return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v);
/* Sorry, only supported in win64/Itanium.. */ /* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_WIN64)) #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_M_X64))
FLAC__uint64 idx; {
_BitScanReverse64(&idx, v); unsigned long idx;
return idx ^ 63U; _BitScanReverse64(&idx, v);
return idx;
}
#else #else
/* Brain-damaged compilers will use the fastest possible way that is, /* Brain-damaged compilers will use the fastest possible way that is,
de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf) de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf)
(C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 LGPL (v2 or later). (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain).
*/ */
static const unsigned char DEBRUIJN_IDX64[64]={ {
0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, static const unsigned char DEBRUIJN_IDX64[64]={
5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40,
63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57,
62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56,
}; 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58
int ret; };
ret= v>0; v|= v>>1;
v|= v>>1; v|= v>>2;
v|= v>>2; v|= v>>4;
v|= v>>4; v|= v>>8;
v|= v>>8; v|= v>>16;
v|= v>>16; v|= v>>32;
v|= v>>32; v= (v>>1)+1;
v= (v>>1)+1; return DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F];
ret+=DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F]; }
return ret;
#endif #endif
} }
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -50,7 +50,7 @@ typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *b
*/ */
FLAC__BitReader *FLAC__bitreader_new(void); FLAC__BitReader *FLAC__bitreader_new(void);
void FLAC__bitreader_delete(FLAC__BitReader *br); void FLAC__bitreader_delete(FLAC__BitReader *br);
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd); FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd);
void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */ void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */
FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br);
void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out);
@ -82,19 +82,10 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F
FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val); FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val);
FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter); FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter);
FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
#ifndef FLAC__NO_ASM
# ifdef FLAC__CPU_IA32
# ifdef FLAC__HAS_NASM
FLAC__bool FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
# endif
# endif
#endif
#if 0 /* UNUSED */ #if 0 /* UNUSED */
FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter); FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter);
FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter); FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter);
#endif #endif
FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen); FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen);
FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen); FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen);
FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br);
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -41,49 +41,59 @@
typedef enum { typedef enum {
FLAC__CPUINFO_TYPE_IA32, FLAC__CPUINFO_TYPE_IA32,
FLAC__CPUINFO_TYPE_PPC, FLAC__CPUINFO_TYPE_X86_64,
FLAC__CPUINFO_TYPE_UNKNOWN FLAC__CPUINFO_TYPE_UNKNOWN
} FLAC__CPUInfo_Type; } FLAC__CPUInfo_Type;
#if defined FLAC__CPU_IA32
typedef struct { typedef struct {
FLAC__bool cpuid;
FLAC__bool bswap;
FLAC__bool cmov; FLAC__bool cmov;
FLAC__bool mmx; FLAC__bool mmx;
FLAC__bool fxsr;
FLAC__bool sse; FLAC__bool sse;
FLAC__bool sse2; FLAC__bool sse2;
FLAC__bool sse3; FLAC__bool sse3;
FLAC__bool ssse3; FLAC__bool ssse3;
FLAC__bool _3dnow; FLAC__bool sse41;
FLAC__bool ext3dnow; FLAC__bool sse42;
FLAC__bool extmmx; FLAC__bool avx;
FLAC__bool avx2;
FLAC__bool fma;
} FLAC__CPUInfo_IA32; } FLAC__CPUInfo_IA32;
#elif defined FLAC__CPU_X86_64
typedef struct { typedef struct {
FLAC__bool altivec; FLAC__bool sse3;
FLAC__bool ppc64; FLAC__bool ssse3;
} FLAC__CPUInfo_PPC; FLAC__bool sse41;
FLAC__bool sse42;
FLAC__bool avx;
FLAC__bool avx2;
FLAC__bool fma;
} FLAC__CPUInfo_x86;
#endif
typedef struct { typedef struct {
FLAC__bool use_asm; FLAC__bool use_asm;
FLAC__CPUInfo_Type type; FLAC__CPUInfo_Type type;
union { #if defined FLAC__CPU_IA32
FLAC__CPUInfo_IA32 ia32; FLAC__CPUInfo_IA32 ia32;
FLAC__CPUInfo_PPC ppc; #elif defined FLAC__CPU_X86_64
} data; FLAC__CPUInfo_x86 x86;
#endif
} FLAC__CPUInfo; } FLAC__CPUInfo;
void FLAC__cpu_info(FLAC__CPUInfo *info); void FLAC__cpu_info(FLAC__CPUInfo *info);
#ifndef FLAC__NO_ASM #ifndef FLAC__NO_ASM
#ifdef FLAC__CPU_IA32 # if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
#ifdef FLAC__HAS_NASM
FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void); FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx); void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx);
FLAC__uint32 FLAC__cpu_info_extended_amd_asm_ia32(void); # endif
#endif # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#endif FLAC__uint32 FLAC__cpu_have_cpuid_x86(void);
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx);
FLAC__uint32 FLAC__cpu_xgetbv_x86(void);
# endif
#endif #endif
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -51,7 +51,7 @@ FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len);
*/ */
extern unsigned const FLAC__crc16_table[256]; extern unsigned const FLAC__crc16_table[256];
#define FLAC__CRC16_UPDATE(data, crc) (((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])) #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])
/* this alternate may be faster on some systems/compilers */ /* this alternate may be faster on some systems/compilers */
#if 0 #if 0
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff) #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff)

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -37,6 +37,7 @@
#include <config.h> #include <config.h>
#endif #endif
#include "cpu.h"
#include "float.h" #include "float.h"
#include "../../../format.h" #include "../../../format.h"
@ -54,14 +55,22 @@
*/ */
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
# ifndef FLAC__NO_ASM # ifndef FLAC__NO_ASM
# ifdef FLAC__CPU_IA32 # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__HAS_NASM # ifdef FLAC__SSE2_SUPPORTED
unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
# endif
# ifdef FLAC__SSSE3_SUPPORTED
unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
# endif # endif
# endif # endif
# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
# endif
# endif # endif
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
#else #else
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson * Copyright (C) 2004-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -37,6 +37,7 @@
#include <config.h> #include <config.h>
#endif #endif
#include "cpu.h"
#include "float.h" #include "float.h"
#include "../../../format.h" #include "../../../format.h"
@ -75,7 +76,15 @@ void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigne
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
# endif
# endif
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE_SUPPORTED
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
# endif # endif
# endif # endif
#endif #endif
@ -145,6 +154,22 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
# ifdef FLAC__HAS_NASM # ifdef FLAC__HAS_NASM
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif
# endif
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE2_SUPPORTED
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif
# ifdef FLAC__AVX2_SUPPORTED
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
# endif # endif
# endif # endif
#endif #endif
@ -173,11 +198,17 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
# ifdef FLAC__HAS_NASM # ifdef FLAC__HAS_NASM
void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
# endif /* FLAC__HAS_NASM */ # endif /* FLAC__HAS_NASM */
# elif defined FLAC__CPU_PPC # endif /* FLAC__CPU_IA32 */
void FLAC__lpc_restore_signal_asm_ppc_altivec_16(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
void FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); # ifdef FLAC__SSE2_SUPPORTED
# endif/* FLAC__CPU_IA32 || FLAC__CPU_PPC */ void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
# endif
# endif
#endif /* FLAC__NO_ASM */ #endif /* FLAC__NO_ASM */
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY

View file

@ -28,11 +28,17 @@
#include "../../../ordinals.h" #include "../../../ordinals.h"
typedef union {
FLAC__byte *p8;
FLAC__int16 *p16;
FLAC__int32 *p32;
} FLAC__multibyte;
typedef struct { typedef struct {
FLAC__uint32 in[16]; FLAC__uint32 in[16];
FLAC__uint32 buf[4]; FLAC__uint32 buf[4];
FLAC__uint32 bytes[2]; FLAC__uint32 bytes[2];
FLAC__byte *internal_buf; FLAC__multibyte internal_buf;
size_t capacity; size_t capacity;
} FLAC__MD5Context; } FLAC__MD5Context;

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2002-2009 Josh Coalson * Copyright (C) 2002-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -0,0 +1,67 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FLAC__PRIVATE__STREAM_ENCODER_H
#define FLAC__PRIVATE__STREAM_ENCODER_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/*
* This is used to avoid overflow with unusual signals in 32-bit
* accumulator in the *precompute_partition_info_sums_* functions.
*/
#define FLAC__MAX_EXTRA_RESIDUAL_BPS 4
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "cpu.h"
#include "../../../format.h"
#ifdef FLAC__SSE2_SUPPORTED
extern void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#endif
#ifdef FLAC__SSSE3_SUPPORTED
extern void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#endif
#ifdef FLAC__AVX2_SUPPORTED
extern void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#endif
#endif
#endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2006-2009 Josh Coalson * Copyright (C) 2006-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -65,6 +65,8 @@ void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L);
void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L); void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L);
void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L); void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L);
void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p); void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p);
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L); void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L);
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -40,6 +40,7 @@
typedef struct FLAC__StreamDecoderProtected { typedef struct FLAC__StreamDecoderProtected {
FLAC__StreamDecoderState state; FLAC__StreamDecoderState state;
FLAC__StreamDecoderInitStatus initstate;
unsigned channels; unsigned channels;
FLAC__ChannelAssignment channel_assignment; FLAC__ChannelAssignment channel_assignment;
unsigned bits_per_sample; unsigned bits_per_sample;

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -59,6 +59,8 @@ typedef enum {
FLAC__APODIZATION_RECTANGLE, FLAC__APODIZATION_RECTANGLE,
FLAC__APODIZATION_TRIANGLE, FLAC__APODIZATION_TRIANGLE,
FLAC__APODIZATION_TUKEY, FLAC__APODIZATION_TUKEY,
FLAC__APODIZATION_PARTIAL_TUKEY,
FLAC__APODIZATION_PUNCHOUT_TUKEY,
FLAC__APODIZATION_WELCH FLAC__APODIZATION_WELCH
} FLAC__ApodizationFunction; } FLAC__ApodizationFunction;
@ -71,6 +73,11 @@ typedef struct {
struct { struct {
FLAC__real p; FLAC__real p;
} tukey; } tukey;
struct {
FLAC__real p;
FLAC__real start;
FLAC__real end;
} multiple_tukey;
} parameters; } parameters;
} FLAC__ApodizationSpecification; } FLAC__ApodizationSpecification;

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -50,11 +50,6 @@
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef M_LN2
/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
#define M_LN2 0.69314718055994530942
#endif
#if !defined(HAVE_LROUND) #if !defined(HAVE_LROUND)
#if defined(_MSC_VER) #if defined(_MSC_VER)
#include <float.h> #include <float.h>
@ -65,7 +60,7 @@
static inline long int lround(double x) { static inline long int lround(double x) {
return (long)(x + copysign (0.5, x)); return (long)(x + copysign (0.5, x));
} }
//If this fails, we are in the precence of a mid 90's compiler..move along... /* If this fails, we are in the presence of a mid 90's compiler, move along... */
#endif #endif
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len)
@ -160,7 +155,7 @@ void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_o
lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */ lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */
error[i] = err; error[i] = err;
/* see SF bug #1601812 http://sourceforge.net/tracker/index.php?func=detail&aid=1601812&group_id=13478&atid=113478 */ /* see SF bug https://sourceforge.net/p/flac/bugs/234/ */
if(err == 0.0) { if(err == 0.0) {
*max_order = i+1; *max_order = i+1;
return; return;
@ -264,7 +259,12 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order,
return 0; return 0;
} }
void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) #if defined(_MSC_VER)
// silence MSVC warnings about __restrict modifier
#pragma warning ( disable : 4028 )
#endif
void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
FLAC__int64 sumo; FLAC__int64 sumo;
@ -524,7 +524,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, u
} }
#endif #endif
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
unsigned i, j; unsigned i, j;
@ -780,7 +780,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
FLAC__int64 sumo; FLAC__int64 sumo;
@ -1041,7 +1041,7 @@ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, c
} }
#endif #endif
void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
unsigned i, j; unsigned i, j;
@ -1295,6 +1295,10 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
} }
#endif #endif
#if defined(_MSC_VER)
#pragma warning ( default : 4028 )
#endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples) FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples)

View file

@ -1,4 +1,4 @@
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -7,6 +7,7 @@
#include "include/private/md5.h" #include "include/private/md5.h"
#include "../alloc.h" #include "../alloc.h"
#include "../endswap.h"
/* /*
* This code implements the MD5 message-digest algorithm. * This code implements the MD5 message-digest algorithm.
@ -223,7 +224,7 @@ void FLAC__MD5Init(FLAC__MD5Context *ctx)
ctx->bytes[0] = 0; ctx->bytes[0] = 0;
ctx->bytes[1] = 0; ctx->bytes[1] = 0;
ctx->internal_buf = 0; ctx->internal_buf.p8= 0;
ctx->capacity = 0; ctx->capacity = 0;
} }
@ -259,9 +260,9 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
byteSwap(ctx->buf, 4); byteSwap(ctx->buf, 4);
memcpy(digest, ctx->buf, 16); memcpy(digest, ctx->buf, 16);
if(0 != ctx->internal_buf) { if (0 != ctx->internal_buf.p8) {
free(ctx->internal_buf); free(ctx->internal_buf.p8);
ctx->internal_buf = 0; ctx->internal_buf.p8= 0;
ctx->capacity = 0; ctx->capacity = 0;
} }
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
@ -270,58 +271,124 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
/* /*
* Convert the incoming audio signal to a byte stream * Convert the incoming audio signal to a byte stream
*/ */
static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
{ {
FLAC__byte *buf_ = mbuf->p8;
FLAC__int16 *buf16 = mbuf->p16;
FLAC__int32 *buf32 = mbuf->p32;
FLAC__int32 a_word;
unsigned channel, sample; unsigned channel, sample;
register FLAC__int32 a_word;
register FLAC__byte *buf_ = buf;
#if WORDS_BIGENDIAN /* Storage in the output buffer, buf, is little endian. */
#else
if(channels == 2 && bytes_per_sample == 2) { #define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels)
FLAC__int16 *buf1_ = ((FLAC__int16*)buf_) + 1;
memcpy(buf_, signal[0], sizeof(FLAC__int32) * samples); /* First do the most commonly used combinations. */
for(sample = 0; sample < samples; sample++, buf1_+=2) switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) {
*buf1_ = (FLAC__int16)signal[1][sample]; /* One byte per sample. */
} case (BYTES_CHANNEL_SELECTOR (1, 1)):
else if(channels == 1 && bytes_per_sample == 2) { for (sample = 0; sample < samples; sample++)
FLAC__int16 *buf1_ = (FLAC__int16*)buf_; *buf_++ = signal[0][sample];
for(sample = 0; sample < samples; sample++) return;
*buf1_++ = (FLAC__int16)signal[0][sample];
} case (BYTES_CHANNEL_SELECTOR (1, 2)):
else for (sample = 0; sample < samples; sample++) {
#endif *buf_++ = signal[0][sample];
if(bytes_per_sample == 2) { *buf_++ = signal[1][sample];
if(channels == 2) { }
for(sample = 0; sample < samples; sample++) { return;
case (BYTES_CHANNEL_SELECTOR (1, 4)):
for (sample = 0; sample < samples; sample++) {
*buf_++ = signal[0][sample];
*buf_++ = signal[1][sample];
*buf_++ = signal[2][sample];
*buf_++ = signal[3][sample];
}
return;
case (BYTES_CHANNEL_SELECTOR (1, 6)):
for (sample = 0; sample < samples; sample++) {
*buf_++ = signal[0][sample];
*buf_++ = signal[1][sample];
*buf_++ = signal[2][sample];
*buf_++ = signal[3][sample];
*buf_++ = signal[4][sample];
*buf_++ = signal[5][sample];
}
return;
case (BYTES_CHANNEL_SELECTOR (1, 8)):
for (sample = 0; sample < samples; sample++) {
*buf_++ = signal[0][sample];
*buf_++ = signal[1][sample];
*buf_++ = signal[2][sample];
*buf_++ = signal[3][sample];
*buf_++ = signal[4][sample];
*buf_++ = signal[5][sample];
*buf_++ = signal[6][sample];
*buf_++ = signal[7][sample];
}
return;
/* Two bytes per sample. */
case (BYTES_CHANNEL_SELECTOR (2, 1)):
for (sample = 0; sample < samples; sample++)
*buf16++ = H2LE_16(signal[0][sample]);
return;
case (BYTES_CHANNEL_SELECTOR (2, 2)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (2, 4)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
*buf16++ = H2LE_16(signal[2][sample]);
*buf16++ = H2LE_16(signal[3][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (2, 6)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
*buf16++ = H2LE_16(signal[2][sample]);
*buf16++ = H2LE_16(signal[3][sample]);
*buf16++ = H2LE_16(signal[4][sample]);
*buf16++ = H2LE_16(signal[5][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (2, 8)):
for (sample = 0; sample < samples; sample++) {
*buf16++ = H2LE_16(signal[0][sample]);
*buf16++ = H2LE_16(signal[1][sample]);
*buf16++ = H2LE_16(signal[2][sample]);
*buf16++ = H2LE_16(signal[3][sample]);
*buf16++ = H2LE_16(signal[4][sample]);
*buf16++ = H2LE_16(signal[5][sample]);
*buf16++ = H2LE_16(signal[6][sample]);
*buf16++ = H2LE_16(signal[7][sample]);
}
return;
/* Three bytes per sample. */
case (BYTES_CHANNEL_SELECTOR (3, 1)):
for (sample = 0; sample < samples; sample++) {
a_word = signal[0][sample]; a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
a_word = signal[1][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; *buf_++ = (FLAC__byte)a_word;
} }
} return;
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) { case (BYTES_CHANNEL_SELECTOR (3, 2)):
a_word = signal[0][sample]; for (sample = 0; sample < samples; sample++) {
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
else {
for(sample = 0; sample < samples; sample++) {
for(channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
}
}
else if(bytes_per_sample == 3) {
if(channels == 2) {
for(sample = 0; sample < samples; sample++) {
a_word = signal[0][sample]; a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
@ -331,60 +398,90 @@ static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], u
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; *buf_++ = (FLAC__byte)a_word;
} }
} return;
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) { /* Four bytes per sample. */
a_word = signal[0][sample]; case (BYTES_CHANNEL_SELECTOR (4, 1)):
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; for (sample = 0; sample < samples; sample++)
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf32++ = H2LE_32(signal[0][sample]);
*buf_++ = (FLAC__byte)a_word; return;
case (BYTES_CHANNEL_SELECTOR (4, 2)):
for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
} }
} return;
else {
for(sample = 0; sample < samples; sample++) { case (BYTES_CHANNEL_SELECTOR (4, 4)):
for(channel = 0; channel < channels; channel++) { for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
*buf32++ = H2LE_32(signal[2][sample]);
*buf32++ = H2LE_32(signal[3][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (4, 6)):
for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
*buf32++ = H2LE_32(signal[2][sample]);
*buf32++ = H2LE_32(signal[3][sample]);
*buf32++ = H2LE_32(signal[4][sample]);
*buf32++ = H2LE_32(signal[5][sample]);
}
return;
case (BYTES_CHANNEL_SELECTOR (4, 8)):
for (sample = 0; sample < samples; sample++) {
*buf32++ = H2LE_32(signal[0][sample]);
*buf32++ = H2LE_32(signal[1][sample]);
*buf32++ = H2LE_32(signal[2][sample]);
*buf32++ = H2LE_32(signal[3][sample]);
*buf32++ = H2LE_32(signal[4][sample]);
*buf32++ = H2LE_32(signal[5][sample]);
*buf32++ = H2LE_32(signal[6][sample]);
*buf32++ = H2LE_32(signal[7][sample]);
}
return;
default:
break;
}
/* General version. */
switch (bytes_per_sample) {
case 1:
for (sample = 0; sample < samples; sample++)
for (channel = 0; channel < channels; channel++)
*buf_++ = signal[channel][sample];
return;
case 2:
for (sample = 0; sample < samples; sample++)
for (channel = 0; channel < channels; channel++)
*buf16++ = H2LE_16(signal[channel][sample]);
return;
case 3:
for (sample = 0; sample < samples; sample++)
for (channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample]; a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; *buf_++ = (FLAC__byte)a_word;
} }
} return;
}
} case 4:
else if(bytes_per_sample == 1) { for (sample = 0; sample < samples; sample++)
if(channels == 2) { for (channel = 0; channel < channels; channel++)
for(sample = 0; sample < samples; sample++) { *buf32++ = H2LE_32(signal[channel][sample]);
a_word = signal[0][sample]; return;
*buf_++ = (FLAC__byte)a_word;
a_word = signal[1][sample]; default:
*buf_++ = (FLAC__byte)a_word; break;
}
}
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) {
a_word = signal[0][sample];
*buf_++ = (FLAC__byte)a_word;
}
}
else {
for(sample = 0; sample < samples; sample++) {
for(channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word;
}
}
}
}
else { /* bytes_per_sample == 4, maybe optimize more later */
for(sample = 0; sample < samples; sample++) {
for(channel = 0; channel < channels; channel++) {
a_word = signal[channel][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word;
}
}
} }
} }
@ -396,26 +493,26 @@ FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const
const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
/* overflow check */ /* overflow check */
if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
return false; return false;
if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
return false; return false;
if(ctx->capacity < bytes_needed) { if (ctx->capacity < bytes_needed) {
FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf, bytes_needed); FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf.p8, bytes_needed);
if(0 == tmp) { if (0 == tmp) {
free(ctx->internal_buf); free(ctx->internal_buf.p8);
if(0 == (ctx->internal_buf = (FLAC__byte*) safe_malloc_(bytes_needed))) if (0 == (ctx->internal_buf.p8= (FLAC__byte*) safe_malloc_(bytes_needed)))
return false; return false;
} }
else else
ctx->internal_buf = tmp; ctx->internal_buf.p8= tmp;
ctx->capacity = bytes_needed; ctx->capacity = bytes_needed;
} }
format_input_(ctx->internal_buf, signal, channels, samples, bytes_per_sample); format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample);
FLAC__MD5Update(ctx, ctx->internal_buf, bytes_needed); FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed);
return true; return true;
} }

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,10 +30,14 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "include/private/memory.h" #include "include/private/memory.h"
#include "../assert.h" #include "../assert.h"
#include "../alloc.h" #include "../alloc.h"
@ -46,25 +50,8 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
#ifdef FLAC__ALIGN_MALLOC_DATA #ifdef FLAC__ALIGN_MALLOC_DATA
/* align on 32-byte (256-bit) boundary */ /* align on 32-byte (256-bit) boundary */
x = safe_malloc_add_2op_(bytes, /*+*/31); x = safe_malloc_add_2op_(bytes, /*+*/31L);
#ifdef SIZEOF_VOIDP *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L);
#if SIZEOF_VOIDP == 4
/* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */
*aligned_address = (void*)(((unsigned)x + 31) & -32);
#elif SIZEOF_VOIDP == 8
*aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
#else
# error Unsupported sizeof(void*)
#endif
#else
/* there's got to be a better way to do this right for all archs */
if(sizeof(void*) == sizeof(unsigned))
*aligned_address = (void*)(((unsigned)x + 31) & -32);
else if(sizeof(void*) == sizeof(FLAC__uint64))
*aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
else
return 0;
#endif
#else #else
x = safe_malloc_(bytes); x = safe_malloc_(bytes);
*aligned_address = x; *aligned_address = x;

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -70,7 +70,7 @@ FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC =
* *
***********************************************************************/ ***********************************************************************/
static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
/*********************************************************************** /***********************************************************************
* *
@ -86,7 +86,7 @@ static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder);
static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder); static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder);
static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj); static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length);
static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj); static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj);
static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj); static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj);
static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder); static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
@ -141,9 +141,6 @@ typedef struct FLAC__StreamDecoderPrivate {
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[]); 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): */ /* 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[]); 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[]);
FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
void *client_data; void *client_data;
FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
FLAC__BitReader *input; FLAC__BitReader *input;
@ -380,7 +377,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
#if FLAC__HAS_OGG #if FLAC__HAS_OGG
decoder->private_->is_ogg = is_ogg; decoder->private_->is_ogg = is_ogg;
if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect)) if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
return decoder->protected_->state = FLAC__STREAM_DECODER_OGG_ERROR; return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
#endif #endif
/* /*
@ -391,42 +388,44 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; 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_64bit = FLAC__lpc_restore_signal_wide;
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal;
decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block;
/* now override with asm where appropriate */ /* now override with asm where appropriate */
#ifndef FLAC__NO_ASM #ifndef FLAC__NO_ASM
if(decoder->private_->cpuinfo.use_asm) { if(decoder->private_->cpuinfo.use_asm) {
#ifdef FLAC__CPU_IA32 #ifdef FLAC__CPU_IA32
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
#ifdef FLAC__HAS_NASM #ifdef FLAC__HAS_NASM
#if 1 /*@@@@@@ OPT: not clearly faster, needs more testing */ decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */
if(decoder->private_->cpuinfo.data.ia32.bswap) if(decoder->private_->cpuinfo.ia32.mmx) {
decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap;
#endif
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 = 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 = FLAC__lpc_restore_signal_asm_ia32_mmx;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx;
} }
else { else {
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; 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 = FLAC__lpc_restore_signal_asm_ia32;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32;
} }
#endif #endif
#elif defined FLAC__CPU_PPC #ifdef FLAC__HAS_X86INTRIN
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC); # if defined FLAC__SSE2_SUPPORTED && !defined FLAC__HAS_NASM /* OPT_SSE: not better than MMX asm */
if(decoder->private_->cpuinfo.data.ppc.altivec) { if(decoder->private_->cpuinfo.ia32.sse2) {
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse2;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8;
} }
# endif
# if defined FLAC__SSE4_1_SUPPORTED
if(decoder->private_->cpuinfo.ia32.sse41) {
decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41;
}
# endif
#endif
#elif defined FLAC__CPU_X86_64
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64);
/* No useful SSE optimizations yet */
#endif #endif
} }
#endif #endif
/* from here on, errors are fatal */ /* from here on, errors are fatal */
if(!FLAC__bitreader_init(decoder->private_->input, decoder->private_->cpuinfo, read_callback_, decoder)) { if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
} }
@ -528,10 +527,10 @@ static FLAC__StreamDecoderInitStatus init_FILE_internal_(
FLAC__ASSERT(0 != file); FLAC__ASSERT(0 != file);
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED); return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
if(0 == write_callback || 0 == error_callback) if(0 == write_callback || 0 == error_callback)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS); return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
/* /*
* To make sure that our file does not go unclosed after an error, we * To make sure that our file does not go unclosed after an error, we
@ -602,10 +601,10 @@ static FLAC__StreamDecoderInitStatus init_file_internal_(
* in FLAC__stream_decoder_init_FILE() before the FILE* is assigned. * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned.
*/ */
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED); return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
if(0 == write_callback || 0 == error_callback) if(0 == write_callback || 0 == error_callback)
return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS); return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
file = filename? flac_fopen(filename, "rb") : stdin; file = filename? flac_fopen(filename, "rb") : stdin;
@ -652,7 +651,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
return true; return true;
/* see the comment in FLAC__seekable_stream_decoder_reset() as to why we /* see the comment in FLAC__stream_decoder_reset() as to why we
* always call FLAC__MD5Final() * always call FLAC__MD5Final()
*/ */
FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
@ -1316,9 +1315,6 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne
memset(tmp, 0, sizeof(FLAC__int32)*4); memset(tmp, 0, sizeof(FLAC__int32)*4);
decoder->private_->output[i] = tmp + 4; decoder->private_->output[i] = tmp + 4;
/* 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])) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
@ -1348,12 +1344,12 @@ FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
{ {
FLAC__uint32 x; FLAC__uint32 x;
unsigned i, id_; unsigned i, id;
FLAC__bool first = true; FLAC__bool first = true;
FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
for(i = id_ = 0; i < 4; ) { for(i = id = 0; i < 4; ) {
if(decoder->private_->cached) { if(decoder->private_->cached) {
x = (FLAC__uint32)decoder->private_->lookahead; x = (FLAC__uint32)decoder->private_->lookahead;
decoder->private_->cached = false; decoder->private_->cached = false;
@ -1365,19 +1361,23 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
if(x == FLAC__STREAM_SYNC_STRING[i]) { if(x == FLAC__STREAM_SYNC_STRING[i]) {
first = true; first = true;
i++; i++;
id_ = 0; id = 0;
continue; continue;
} }
if(x == ID3V2_TAG_[id_]) {
id_++; if(id >= 3)
return false;
if(x == ID3V2_TAG_[id]) {
id++;
i = 0; i = 0;
if(id_ == 3) { if(id == 3) {
if(!skip_id3v2_tag_(decoder)) if(!skip_id3v2_tag_(decoder))
return false; /* skip_id3v2_tag_ sets the state for us */ return false; /* skip_id3v2_tag_ sets the state for us */
} }
continue; continue;
} }
id_ = 0; id = 0;
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
decoder->private_->header_warmup[0] = (FLAC__byte)x; decoder->private_->header_warmup[0] = (FLAC__byte)x;
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
@ -1446,6 +1446,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
unsigned real_length = length; unsigned real_length = length;
FLAC__StreamMetadata block; FLAC__StreamMetadata block;
memset(&block, 0, sizeof(block));
block.is_last = is_last; block.is_last = is_last;
block.type = (FLAC__MetadataType)type; block.type = (FLAC__MetadataType)type;
block.length = length; block.length = length;
@ -1470,36 +1471,37 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
return false; /* read_callback_ sets the state for us */ return false; /* read_callback_ sets the state for us */
} }
else { else {
FLAC__bool ok = true;
switch(type) { switch(type) {
case FLAC__METADATA_TYPE_PADDING: case FLAC__METADATA_TYPE_PADDING:
/* skip the padding bytes */ /* skip the padding bytes */
if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length))
return false; /* read_callback_ sets the state for us */ ok = false; /* read_callback_ sets the state for us */
break; break;
case FLAC__METADATA_TYPE_APPLICATION: case FLAC__METADATA_TYPE_APPLICATION:
/* remember, we read the ID already */ /* remember, we read the ID already */
if(real_length > 0) { if(real_length > 0) {
if(0 == (block.data.application.data = (FLAC__byte*) malloc(real_length))) { if(0 == (block.data.application.data = (FLAC__byte*) malloc(real_length))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; ok = false;
} }
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length))
return false; /* read_callback_ sets the state for us */ ok = false; /* read_callback_ sets the state for us */
} }
else else
block.data.application.data = 0; block.data.application.data = 0;
break; break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT: case FLAC__METADATA_TYPE_VORBIS_COMMENT:
if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment)) if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length))
return false; ok = false;
break; break;
case FLAC__METADATA_TYPE_CUESHEET: case FLAC__METADATA_TYPE_CUESHEET:
if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet))
return false; ok = false;
break; break;
case FLAC__METADATA_TYPE_PICTURE: case FLAC__METADATA_TYPE_PICTURE:
if(!read_metadata_picture_(decoder, &block.data.picture)) if(!read_metadata_picture_(decoder, &block.data.picture))
return false; ok = false;
break; break;
case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_STREAMINFO:
case FLAC__METADATA_TYPE_SEEKTABLE: case FLAC__METADATA_TYPE_SEEKTABLE:
@ -1509,16 +1511,16 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
if(real_length > 0) { if(real_length > 0) {
if(0 == (block.data.unknown.data = (FLAC__byte*) malloc(real_length))) { if(0 == (block.data.unknown.data = (FLAC__byte*) malloc(real_length))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; ok = false;
} }
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length))
return false; /* read_callback_ sets the state for us */ ok = false; /* read_callback_ sets the state for us */
} }
else else
block.data.unknown.data = 0; block.data.unknown.data = 0;
break; break;
} }
if(!decoder->private_->is_seeking && decoder->private_->metadata_callback) if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback)
decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
/* now we have to free any malloc()ed data in the block */ /* now we have to free any malloc()ed data in the block */
@ -1563,6 +1565,9 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
free(block.data.unknown.data); free(block.data.unknown.data);
break; break;
} }
if(!ok) /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */
return false;
} }
} }
@ -1689,58 +1694,88 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_
return true; return true;
} }
FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj) FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length)
{ {
FLAC__uint32 i; FLAC__uint32 i;
FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
/* read vendor string */ /* read vendor string */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); if (length >= 8) {
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) length -= 8; /* vendor string length + num comments entries alone take 8 bytes */
return false; /* read_callback_ sets the state for us */ FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if(obj->vendor_string.length > 0) { if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
if(0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length))
return false; /* read_callback_ sets the state for us */ return false; /* read_callback_ sets the state for us */
obj->vendor_string.entry[obj->vendor_string.length] = '\0'; if (obj->vendor_string.length > 0) {
} if (length < obj->vendor_string.length) {
else obj->vendor_string.length = 0;
obj->vendor_string.entry = 0; obj->vendor_string.entry = 0;
goto skip;
/* read num comments */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments))
return false; /* read_callback_ sets the state for us */
/* read comments */
if(obj->num_comments > 0) {
if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*) safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
for(i = 0; i < obj->num_comments; i++) {
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
if(obj->comments[i].length > 0) {
if(0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
obj->comments[i].entry[obj->comments[i].length] = '\0';
} }
else else
obj->comments[i].entry = 0; length -= obj->vendor_string.length;
if (0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length))
return false; /* read_callback_ sets the state for us */
obj->vendor_string.entry[obj->vendor_string.length] = '\0';
} }
else
obj->vendor_string.entry = 0;
/* read num comments */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments))
return false; /* read_callback_ sets the state for us */
/* read comments */
if (obj->num_comments > 0) {
if (0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*) safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
for (i = 0; i < obj->num_comments; i++) {
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if (length < 4) {
obj->num_comments = i;
goto skip;
}
else
length -= 4;
if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
if (obj->comments[i].length > 0) {
if (length < obj->comments[i].length) {
obj->comments[i].length = 0;
obj->comments[i].entry = 0;
obj->num_comments = i;
goto skip;
}
else
length -= obj->comments[i].length;
if (0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
obj->comments[i].entry[obj->comments[i].length] = '\0';
}
else
obj->comments[i].entry = 0;
}
}
else
obj->comments = 0;
} }
else {
obj->comments = 0; skip:
if (length > 0) {
/* This will only happen on files with invalid data in comments */
if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length))
return false; /* read_callback_ sets the state for us */
} }
return true; return true;
@ -2655,12 +2690,8 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, un
if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) ) if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) )
*/ */
if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
if(bps <= 16 && subframe->qlp_coeff_precision <= 16) { if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
if(order <= 8) 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);
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 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); 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 else
@ -2708,14 +2739,16 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne
if(decoder->private_->frame.header.blocksize < predictor_order) { if(decoder->private_->frame.header.blocksize < predictor_order) {
send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
return true; /* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */
return false;
} }
} }
else { else {
if(partition_samples < predictor_order) { if(partition_samples < predictor_order) {
send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
return true; /* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */
return false;
} }
} }
@ -2732,7 +2765,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne
if(rice_parameter < pesc) { if(rice_parameter < pesc) {
partitioned_rice_contents->raw_bits[partition] = 0; partitioned_rice_contents->raw_bits[partition] = 0;
u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter))
return false; /* read_callback_ sets the state for us */ return false; /* read_callback_ sets the state for us */
sample += u; sample += u;
} }
@ -3074,12 +3107,7 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
return false; return false;
} }
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#if defined _MSC_VER || defined __MINGW32__
/* with VC++ you have to spoon feed it the casting */
pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)(target_sample - lower_bound_sample) / (FLAC__double)(FLAC__int64)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(FLAC__int64)(upper_bound - lower_bound)) - approx_bytes_per_frame;
#else
pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame; pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame;
#endif
#else #else
/* a little less accurate: */ /* a little less accurate: */
if(upper_bound - lower_bound < 0xffffffff) if(upper_bound - lower_bound < 0xffffffff)
@ -3203,12 +3231,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint
} }
else { else {
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#if defined _MSC_VER || defined __MINGW32__
/* with MSVC you have to spoon feed it the casting */
pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos));
#else
pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos)); pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
#endif
#else #else
/* a little less accurate: */ /* a little less accurate: */
if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff)) if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -55,10 +55,10 @@
#include "include/private/ogg_helper.h" #include "include/private/ogg_helper.h"
#include "include/private/ogg_mapping.h" #include "include/private/ogg_mapping.h"
#endif #endif
#include "include/private/stream_encoder.h"
#include "include/private/stream_encoder_framing.h" #include "include/private/stream_encoder_framing.h"
#include "include/private/window.h" #include "include/private/window.h"
#include "../alloc.h" #include "../alloc.h"
#include "../compat.h"
/* Exact Rice codeword length calculation is off by default. The simple /* Exact Rice codeword length calculation is off by default. The simple
@ -103,16 +103,18 @@ static struct CompressionLevels {
unsigned min_residual_partition_order; unsigned min_residual_partition_order;
unsigned max_residual_partition_order; unsigned max_residual_partition_order;
unsigned rice_parameter_search_dist; unsigned rice_parameter_search_dist;
const char *apodization;
} compression_levels_[] = { } compression_levels_[] = {
{ false, false, 0, 0, false, false, false, 0, 3, 0 }, { false, false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ true , true , 0, 0, false, false, false, 0, 3, 0 }, { true , true , 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ true , false, 0, 0, false, false, false, 0, 3, 0 }, { true , false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ false, false, 6, 0, false, false, false, 0, 4, 0 }, { false, false, 6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
{ true , true , 8, 0, false, false, false, 0, 4, 0 }, { true , true , 8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
{ true , false, 8, 0, false, false, false, 0, 5, 0 }, { true , false, 8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" },
{ true , false, 8, 0, false, false, false, 0, 6, 0 }, { true , false, 8, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
{ true , false, 8, 0, false, false, true , 0, 6, 0 }, { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
{ true , false, 12, 0, false, false, true , 0, 6, 0 } { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2);punchout_tukey(3)" }
/* here we use locale-independent 5e-1 instead of 0.5 or 0,5 */
}; };
@ -342,10 +344,13 @@ typedef struct FLAC__StreamEncoderPrivate {
unsigned current_frame_number; unsigned current_frame_number;
FLAC__MD5Context md5context; FLAC__MD5Context md5context;
FLAC__CPUInfo cpuinfo; FLAC__CPUInfo cpuinfo;
void (*local_precompute_partition_info_sums)(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
#else #else
unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
#endif #endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
@ -873,7 +878,9 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
#endif #endif
encoder->private_->local_precompute_partition_info_sums = precompute_partition_info_sums_;
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor; encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide;
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide;
@ -886,21 +893,23 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
# ifdef FLAC__CPU_IA32 # ifdef FLAC__CPU_IA32
FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
# ifdef FLAC__HAS_NASM # ifdef FLAC__HAS_NASM
if(encoder->private_->cpuinfo.data.ia32.sse) { if(encoder->private_->cpuinfo.ia32.sse) {
if(encoder->protected_->max_lpc_order < 4) if(encoder->protected_->max_lpc_order < 4)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4;
else if(encoder->protected_->max_lpc_order < 8) else if(encoder->protected_->max_lpc_order < 8)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8;
else if(encoder->protected_->max_lpc_order < 12) else if(encoder->protected_->max_lpc_order < 12)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12;
else if(encoder->protected_->max_lpc_order < 16)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16;
else else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
} }
else if(encoder->private_->cpuinfo.data.ia32._3dnow)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow;
else else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
if(encoder->private_->cpuinfo.data.ia32.mmx) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */
if(encoder->private_->cpuinfo.ia32.mmx) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx;
} }
@ -908,16 +917,137 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
} }
if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov)
if(encoder->private_->cpuinfo.ia32.mmx && encoder->private_->cpuinfo.ia32.cmov)
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov; encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov;
# endif /* FLAC__HAS_NASM */ # endif /* FLAC__HAS_NASM */
# endif /* FLAC__CPU_IA32 */ # ifdef FLAC__HAS_X86INTRIN
# if defined FLAC__SSE_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse) {
if(encoder->protected_->max_lpc_order < 4)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4;
else if(encoder->protected_->max_lpc_order < 8)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8;
else if(encoder->protected_->max_lpc_order < 12)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12;
else if(encoder->protected_->max_lpc_order < 16)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16;
else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
}
# endif
# ifdef FLAC__SSE2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse2) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2;
}
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse41) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41;
}
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.avx2) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2;
}
# endif
# ifdef FLAC__SSE2_SUPPORTED
if (encoder->private_->cpuinfo.ia32.sse2) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2;
}
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if (encoder->private_->cpuinfo.ia32.ssse3) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3;
}
# endif
# endif /* FLAC__HAS_X86INTRIN */
# elif defined FLAC__CPU_X86_64
FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64);
# ifdef FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE_SUPPORTED
if(encoder->protected_->max_lpc_order < 4)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4;
else if(encoder->protected_->max_lpc_order < 8)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8;
else if(encoder->protected_->max_lpc_order < 12)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12;
else if(encoder->protected_->max_lpc_order < 16)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16;
# endif
# ifdef FLAC__SSE2_SUPPORTED
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2;
# endif
# ifdef FLAC__SSE4_1_SUPPORTED
if(encoder->private_->cpuinfo.x86.sse41) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41;
}
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.x86.avx2) {
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2;
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2;
}
# endif
# ifdef FLAC__SSE2_SUPPORTED
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2;
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if (encoder->private_->cpuinfo.x86.ssse3) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3;
}
# endif
# endif /* FLAC__HAS_X86INTRIN */
# endif /* FLAC__CPU_... */
} }
# endif /* !FLAC__NO_ASM */ # endif /* !FLAC__NO_ASM */
#endif /* !FLAC__INTEGER_ONLY_LIBRARY */ #endif /* !FLAC__INTEGER_ONLY_LIBRARY */
#if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN
if(encoder->private_->cpuinfo.use_asm) {
# if defined FLAC__CPU_IA32
# ifdef FLAC__SSE2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.sse2)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2;
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if(encoder->private_->cpuinfo.ia32.ssse3)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3;
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.ia32.avx2)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2;
# endif
# elif defined FLAC__CPU_X86_64
# ifdef FLAC__SSE2_SUPPORTED
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2;
# endif
# ifdef FLAC__SSSE3_SUPPORTED
if(encoder->private_->cpuinfo.x86.ssse3)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3;
# endif
# ifdef FLAC__AVX2_SUPPORTED
if(encoder->private_->cpuinfo.x86.avx2)
encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2;
# endif
# endif /* FLAC__CPU_... */
}
#endif /* !FLAC__NO_ASM && FLAC__HAS_X86INTRIN */
/* finally override based on wide-ness if necessary */ /* finally override based on wide-ness if necessary */
if(encoder->private_->use_wide_by_block) { if(encoder->private_->use_wide_by_block) {
encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_wide; encoder->private_->local_fixed_compute_best_predictor = encoder->private_->local_fixed_compute_best_predictor_wide;
} }
/* set state to OK; from here on, errors are fatal and we'll override the state then */ /* set state to OK; from here on, errors are fatal and we'll override the state then */
@ -1152,7 +1282,7 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_(
FLAC__StreamEncoder *encoder, FLAC__StreamEncoder *encoder,
FILE *file, FILE *file,
FLAC__StreamEncoderProgressCallback progress_callback, FLAC__StreamEncoderProgressCallback progress_callback,
void * /*client_data*/, void *client_data,
FLAC__bool is_ogg FLAC__bool is_ogg
) )
{ {
@ -1178,6 +1308,13 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_(
if(file == stdout) if(file == stdout)
file = get_binary_stdout_(); /* just to be safe */ file = get_binary_stdout_(); /* just to be safe */
#ifdef _WIN32
/*
* Windows can suffer quite badly from disk fragmentation. This can be
* reduced significantly by setting the output buffer size to be 10MB.
*/
setvbuf(file, NULL, _IOFBF, 10*1024*1024);
#endif
encoder->private_->file = file; encoder->private_->file = file;
encoder->private_->progress_callback = progress_callback; encoder->private_->progress_callback = progress_callback;
@ -1447,11 +1584,10 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncod
ok &= FLAC__stream_encoder_set_do_mid_side_stereo (encoder, compression_levels_[value].do_mid_side_stereo); ok &= FLAC__stream_encoder_set_do_mid_side_stereo (encoder, compression_levels_[value].do_mid_side_stereo);
ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo); ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo);
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#if 0 #if 1
/* was: */
ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization); ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization);
/* but it's too hard to specify the string in a locale-specific way */
#else #else
/* equivalent to -A tukey(0.5) */
encoder->protected_->num_apodizations = 1; encoder->protected_->num_apodizations = 1;
encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
@ -1555,6 +1691,48 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *en
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
} }
} }
else if(n>15 && 0 == strncmp("partial_tukey(" , specification, 14)) {
FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+14, 0);
const char *si_1 = strchr(specification, '/');
FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.1f;
FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f;
const char *si_2 = strchr((si_1?(si_1+1):specification), '/');
FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f;
if (tukey_parts <= 1) {
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
}else if (encoder->protected_->num_apodizations + tukey_parts < 32){
FLAC__int32 m;
for(m = 0; m < tukey_parts; m++){
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PARTIAL_TUKEY;
}
}
}
else if(n>16 && 0 == strncmp("punchout_tukey(" , specification, 15)) {
FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+15, 0);
const char *si_1 = strchr(specification, '/');
FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.2f;
FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f;
const char *si_2 = strchr((si_1?(si_1+1):specification), '/');
FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f;
if (tukey_parts <= 1) {
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
}else if (encoder->protected_->num_apodizations + tukey_parts < 32){
FLAC__int32 m;
for(m = 0; m < tukey_parts; m++){
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p;
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units);
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PUNCHOUT_TUKEY;
}
}
}
else if(n==5 && 0 == strncmp("welch" , specification, n)) else if(n==5 && 0 == strncmp("welch" , specification, n))
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH; encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH;
if (encoder->protected_->num_apodizations == 32) if (encoder->protected_->num_apodizations == 32)
@ -2236,8 +2414,8 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize)
ok = true; ok = true;
/* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2()
* requires that the input arrays (in our case the integer signals) * require that the input arrays (in our case the integer signals)
* have a buffer of up to 3 zeroes in front (at negative indices) for * have a buffer of up to 3 zeroes in front (at negative indices) for
* alignment purposes; we use 4 in front to keep the data well-aligned. * alignment purposes; we use 4 in front to keep the data well-aligned.
*/ */
@ -2334,6 +2512,12 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize)
case FLAC__APODIZATION_TUKEY: case FLAC__APODIZATION_TUKEY:
FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p); FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p);
break; break;
case FLAC__APODIZATION_PARTIAL_TUKEY:
FLAC__window_partial_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end);
break;
case FLAC__APODIZATION_PUNCHOUT_TUKEY:
FLAC__window_punchout_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end);
break;
case FLAC__APODIZATION_WELCH: case FLAC__APODIZATION_WELCH:
FLAC__window_welch(encoder->private_->window[i], new_blocksize); FLAC__window_welch(encoder->private_->window[i], new_blocksize);
break; break;
@ -3165,7 +3349,7 @@ FLAC__bool process_subframe_(
#endif #endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__double lpc_residual_bits_per_sample; FLAC__double lpc_residual_bits_per_sample;
FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm routines need all the space */ FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm and x86 intrinsic routines need all the space */
FLAC__double lpc_error[FLAC__MAX_LPC_ORDER]; FLAC__double lpc_error[FLAC__MAX_LPC_ORDER];
unsigned min_lpc_order, max_lpc_order, lpc_order; unsigned min_lpc_order, max_lpc_order, lpc_order;
unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision;
@ -3318,9 +3502,9 @@ FLAC__bool process_subframe_(
} }
if(encoder->protected_->do_qlp_coeff_prec_search) { if(encoder->protected_->do_qlp_coeff_prec_search) {
min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
/* try to ensure a 32-bit datapath throughout for 16bps(+1bps for side channel) or less */ /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */
if(subframe_bps <= 17) { if(subframe_bps <= 16) {
max_qlp_coeff_precision = flac_min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION); max_qlp_coeff_precision = flac_min(32 - subframe_bps - FLAC__bitmath_ilog2(lpc_order), FLAC__MAX_QLP_COEFF_PRECISION);
max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision); max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision);
} }
else else
@ -3556,7 +3740,7 @@ unsigned evaluate_lpc_subframe_(
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
) )
{ {
FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /* WATCHOUT: the size is important; some x86 intrinsic routines need more than lpc order elements */
unsigned i, residual_bits, estimate; unsigned i, residual_bits, estimate;
int quantization, ret; int quantization, ret;
const unsigned residual_samples = blocksize - order; const unsigned residual_samples = blocksize - order;
@ -3671,7 +3855,7 @@ unsigned find_best_partition_order_(
max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order);
min_partition_order = flac_min(min_partition_order, max_partition_order); min_partition_order = flac_min(min_partition_order, max_partition_order);
precompute_partition_info_sums_(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps); private_->local_precompute_partition_info_sums(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps);
if(do_escape_coding) if(do_escape_coding)
precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order);
@ -3743,17 +3927,6 @@ unsigned find_best_partition_order_(
return best_residual_bits; return best_residual_bits;
} }
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
extern void precompute_partition_info_sums_32bit_asm_ia32_(
const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
unsigned blocksize,
unsigned predictor_order,
unsigned min_partition_order,
unsigned max_partition_order
);
#endif
void precompute_partition_info_sums_( void precompute_partition_info_sums_(
const FLAC__int32 residual[], const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[], FLAC__uint64 abs_residual_partition_sums[],
@ -3769,21 +3942,12 @@ void precompute_partition_info_sums_(
FLAC__ASSERT(default_partition_samples > predictor_order); FLAC__ASSERT(default_partition_samples > predictor_order);
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
/* slightly pessimistic but still catches all common cases */
/* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */
if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) {
precompute_partition_info_sums_32bit_asm_ia32_(residual, abs_residual_partition_sums, residual_samples + predictor_order, predictor_order, min_partition_order, max_partition_order);
return;
}
#endif
/* first do max_partition_order */ /* first do max_partition_order */
{ {
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order); unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
/* slightly pessimistic but still catches all common cases */ /* WATCHOUT: "+ bps + FLAC__MAX_EXTRA_RESIDUAL_BPS" is the maximum
/* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */ * assumed size of the average residual magnitude */
if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) { if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
FLAC__uint32 abs_residual_partition_sum; FLAC__uint32 abs_residual_partition_sum;
for(partition = residual_sample = 0; partition < partitions; partition++) { for(partition = residual_sample = 0; partition < partitions; partition++) {
@ -4027,8 +4191,35 @@ FLAC__bool set_partitioned_rice_(
* in the partition, so the actual mean is * in the partition, so the actual mean is
* mean/partition_samples * mean/partition_samples
*/ */
#if 0 /* old simple code */
for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1)
; ;
#else
#if defined FLAC__CPU_X86_64 /* and other 64-bit arch, too */
if(mean <= 0x80000000/512) { /* 512: more or less optimal for both 16- and 24-bit input */
#else
if(mean <= 0x80000000/8) { /* 32-bit arch: use 32-bit math if possible */
#endif
FLAC__uint32 k2, mean2 = (FLAC__uint32) mean;
rice_parameter = 0; k2 = partition_samples;
while(k2*8 < mean2) { /* requires: mean <= (2^31)/8 */
rice_parameter += 4; k2 <<= 4; /* tuned for 16-bit input */
}
while(k2 < mean2) { /* requires: mean <= 2^31 */
rice_parameter++; k2 <<= 1;
}
}
else {
rice_parameter = 0; k = partition_samples;
if(mean <= FLAC__U64L(0x8000000000000000)/128) /* usually mean is _much_ smaller than this value */
while(k*128 < mean) { /* requires: mean <= (2^63)/128 */
rice_parameter += 8; k <<= 8; /* tuned for 24-bit input */
}
while(k < mean) { /* requires: mean <= 2^63 */
rice_parameter++; k <<= 1;
}
}
#endif
if(rice_parameter >= rice_parameter_limit) { if(rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE #ifdef DEBUG_VERBOSE
fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2006-2009 Josh Coalson * Copyright (C) 2006-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@ -41,11 +41,6 @@
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef M_PI
/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
#define M_PI 3.14159265358979323846
#endif
void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
{ {
@ -62,7 +57,7 @@ void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
for (n = 0; n <= L/2-1; n++) for (n = 0; n <= L/2-1; n++)
window[n] = 2.0f * n / (float)N; window[n] = 2.0f * n / (float)N;
for (; n <= N; n++) for (; n <= N; n++)
window[n] = 2.0f - 2.0f * (N-n) / (float)N; window[n] = 2.0f - 2.0f * n / (float)N;
} }
} }
@ -72,7 +67,7 @@ void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L)
FLAC__int32 n; FLAC__int32 n;
for (n = 0; n < L; n++) for (n = 0; n < L; n++)
window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N+0.5f) + 0.38f * cos(2.0f * M_PI * ((float)n/(float)N+0.5f))); window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N)));
} }
void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L) void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L)
@ -177,16 +172,16 @@ void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L)
FLAC__int32 n; FLAC__int32 n;
if (L & 1) { if (L & 1) {
for (n = 1; n <= L+1/2; n++) for (n = 1; n <= (L+1)/2; n++)
window[n-1] = 2.0f * n / ((float)L + 1.0f); window[n-1] = 2.0f * n / ((float)L + 1.0f);
for (; n <= L; n++) for (; n <= L; n++)
window[n-1] = - (float)(2 * (L - n + 1)) / ((float)L + 1.0f); window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
} }
else { else {
for (n = 1; n <= L/2; n++) for (n = 1; n <= L/2; n++)
window[n-1] = 2.0f * n / (float)L; window[n-1] = 2.0f * n / ((float)L + 1.0f);
for (; n <= L; n++) for (; n <= L; n++)
window[n-1] = ((float)(2 * (L - n)) + 1.0f) / (float)L; window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
} }
} }
@ -211,6 +206,66 @@ void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__rea
} }
} }
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
{
const FLAC__int32 start_n = (FLAC__int32)(start * L);
const FLAC__int32 end_n = (FLAC__int32)(end * L);
const FLAC__int32 N = end_n - start_n;
FLAC__int32 Np, n, i;
if (p <= 0.0f)
FLAC__window_partial_tukey(window, L, 0.05f, start, end);
else if (p >= 1.0f)
FLAC__window_partial_tukey(window, L, 0.95f, start, end);
else {
Np = (FLAC__int32)(p / 2.0f * N);
for (n = 0; n < start_n && n < L; n++)
window[n] = 0.0f;
for (i = 1; n < (start_n+Np) && n < L; n++, i++)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
for (; n < (end_n-Np) && n < L; n++)
window[n] = 1.0f;
for (i = Np; n < end_n && n < L; n++, i--)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
for (; n < L; n++)
window[n] = 0.0f;
}
}
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
{
const FLAC__int32 start_n = (FLAC__int32)(start * L);
const FLAC__int32 end_n = (FLAC__int32)(end * L);
FLAC__int32 Ns, Ne, n, i;
if (p <= 0.0f)
FLAC__window_punchout_tukey(window, L, 0.05f, start, end);
else if (p >= 1.0f)
FLAC__window_punchout_tukey(window, L, 0.95f, start, end);
else {
Ns = (FLAC__int32)(p / 2.0f * start_n);
Ne = (FLAC__int32)(p / 2.0f * (L - end_n));
for (n = 0, i = 1; n < Ns && n < L; n++, i++)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
for (; n < start_n-Ns && n < L; n++)
window[n] = 1.0f;
for (i = Ns; n < start_n && n < L; n++, i--)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
for (; n < end_n && n < L; n++)
window[n] = 0.0f;
for (i = 1; n < end_n+Ne && n < L; n++, i++)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
for (; n < L - (Ne) && n < L; n++)
window[n] = 1.0f;
for (i = Ne; n < L; n++, i--)
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
}
}
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
{ {
const FLAC__int32 N = L - 1; const FLAC__int32 N = L - 1;

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -500,7 +500,7 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const
* \retval unsigned * \retval unsigned
* The length of the metadata block at the current iterator position. * The length of the metadata block at the current iterator position.
* The is same length as that in the * The is same length as that in the
* <a href="http://flac.sourceforge.net/format.html#metadata_block_header">metadata block header</a>, * <a href="http://xiph.org/flac/format.html#metadata_block_header">metadata block header</a>,
* i.e. the length of the metadata body that follows the header. * i.e. the length of the metadata body that follows the header.
*/ */
FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator);

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View file

@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation * Copyright (C) 2011-2014 Xiph.Org Foundation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -830,28 +830,28 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *en
* The actual values set for each level are: * The actual values set for each level are:
* <table> * <table>
* <tr> * <tr>
* <td><b>level</b><td> * <td><b>level</b></td>
* <td>do mid-side stereo<td> * <td>do mid-side stereo</td>
* <td>loose mid-side stereo<td> * <td>loose mid-side stereo</td>
* <td>apodization<td> * <td>apodization</td>
* <td>max lpc order<td> * <td>max lpc order</td>
* <td>qlp coeff precision<td> * <td>qlp coeff precision</td>
* <td>qlp coeff prec search<td> * <td>qlp coeff prec search</td>
* <td>escape coding<td> * <td>escape coding</td>
* <td>exhaustive model search<td> * <td>exhaustive model search</td>
* <td>min residual partition order<td> * <td>min residual partition order</td>
* <td>max residual partition order<td> * <td>max residual partition order</td>
* <td>rice parameter search dist<td> * <td>rice parameter search dist</td>
* </tr> * </tr>
* <tr> <td><b>0</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> * <tr> <td><b>0</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>1</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> * <tr> <td><b>1</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>2</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> * <tr> <td><b>2</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>3</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>6<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr> * <tr> <td><b>3</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>6</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr>
* <tr> <td><b>4</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr> * <tr> <td><b>4</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr>
* <tr> <td><b>5</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>5<td> <td>0<td> </tr> * <tr> <td><b>5</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>5</td> <td>0</td> </tr>
* <tr> <td><b>6</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>6<td> <td>0<td> </tr> * <tr> <td><b>6</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* <tr> <td><b>7</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr> * <tr> <td><b>7</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* <tr> <td><b>8</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>12<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr> * <tr> <td><b>8</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2);punchout_tukey(3)</td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* </table> * </table>
* *
* \default \c 5 * \default \c 5
@ -920,7 +920,8 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* The available functions are \c bartlett, \c bartlett_hann, * The available functions are \c bartlett, \c bartlett_hann,
* \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop,
* \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall,
* \c rectangle, \c triangle, \c tukey(P), \c welch. * \c rectangle, \c triangle, \c tukey(P), \c partial_tukey(n[/ov[/P]]),
* \c punchout_tukey(n[/ov[/P]]), \c welch.
* *
* For \c gauss(STDDEV), STDDEV specifies the standard deviation * For \c gauss(STDDEV), STDDEV specifies the standard deviation
* (0<STDDEV<=0.5). * (0<STDDEV<=0.5).
@ -929,6 +930,24 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1 * tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1
* corresponds to \c hann. * corresponds to \c hann.
* *
* Specifying \c partial_tukey or \c punchout_tukey works a little
* different. These do not specify a single apodization function, but
* a series of them with some overlap. partial_tukey specifies a series
* of small windows (all treated separately) while punchout_tukey
* specifies a series of windows that have a hole in them. In this way,
* the predictor is constructed with only a part of the block, which
* helps in case a block consists of dissimilar parts.
*
* The three parameters that can be specified for the functions are
* n, ov and P. n is the number of functions to add, ov is the overlap
* of the windows in case of partial_tukey and the overlap in the gaps
* in case of punchout_tukey. P is the fraction of the window that is
* tapered, like with a regular tukey window. The function can be
* specified with only a number, a number and an overlap, or a number
* an overlap and a P, for example, partial_tukey(3), partial_tukey(3/0.3)
* and partial_tukey(3/0.3/0.5) are all valid. ov should be smaller than 1
* and can be negative.
*
* Example specifications are \c "blackman" or * Example specifications are \c "blackman" or
* \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)" * \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)"
* *
@ -941,7 +960,9 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* results in the smallest compressed subframe. * results in the smallest compressed subframe.
* *
* Note that each function specified causes the encoder to occupy a * Note that each function specified causes the encoder to occupy a
* floating point array in which to store the window. * floating point array in which to store the window. Also note that the
* values of P, STDDEV and ov are locale-specific, so if the comma
* separator specified by the locale is a comma, a comma should be used.
* *
* \default \c "tukey(0.5)" * \default \c "tukey(0.5)"
* \param encoder An encoder instance to set. * \param encoder An encoder instance to set.

View file

@ -0,0 +1,69 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2013-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef _WIN32
#ifndef flac__win_utf8_io_h
#define flac__win_utf8_io_h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <windows.h>
int get_utf8_argv(int *argc, char ***argv);
int printf_utf8(const char *format, ...);
int fprintf_utf8(FILE *stream, const char *format, ...);
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr);
FILE *fopen_utf8(const char *filename, const char *mode);
int stat_utf8(const char *path, struct stat *buffer);
int _stat64_utf8(const char *path, struct __stat64 *buffer);
int chmod_utf8(const char *filename, int pmode);
int utime_utf8(const char *filename, struct utimbuf *times);
int unlink_utf8(const char *filename);
int rename_utf8(const char *oldname, const char *newname);
size_t strlen_utf8(const char *str);
int win_get_console_width(void);
int print_console(FILE *stream, const wchar_t *text, size_t len);
HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
#endif