shithub: riscv

Download patch

ref: a5d6746e4d2dc7961910ce7d1729f5500a4dc0f3
parent: 341502a0fd20bd3188b8d4e100b2d975f2d94007
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Fri Sep 9 12:15:52 EDT 2022

libFLAC: update 1.3.4 → 1.4.0

--- a/sys/src/cmd/audio/libFLAC/FLAC/all.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/all.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -147,7 +147,7 @@
  * library.
  *
  * Also, there are several places in the libFLAC code with comments marked
- * with "OPT:" where a #define can be changed to enable code that might be
+ * with "OPT:" where a \#define can be changed to enable code that might be
  * faster on a specific platform.  Experimenting with these can yield faster
  * binaries.
  */
@@ -159,9 +159,9 @@
  * the libraries to newer versions of FLAC.
  *
  * One simple facility for making porting easier that has been added
- * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each
+ * in FLAC 1.1.3 is a set of \#defines in \c export.h of each
  * library's includes (e.g. \c include/FLAC/export.h).  The
- * \c #defines mirror the libraries'
+ * \#defines mirror the libraries'
  * <A HREF="http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning">libtool version numbers</A>,
  * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT,
  * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE.
@@ -355,6 +355,85 @@
  * FLAC frame header length has not changed, so to skip the proper
  * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN +
  * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN
+ */
+
+/** \defgroup porting_1_3_4_to_1_4_0 Porting from FLAC 1.3.4 to 1.4.0
+ *  \ingroup porting
+ *
+ *  \brief
+ *  This module describes porting from FLAC 1.3.4 to FLAC 1.4.0.
+ *
+ * \section porting_1_3_4_to_1_4_0_summary Summary
+ *
+ * Between FLAC 1.3.4 and FLAC 1.4.0, there have four breaking changes
+ * - the function get_client_data_from_decoder has been renamed to
+ *   FLAC__get_decoder_client_data
+ * - some data types in the FLAC__Frame struct have changed
+ * - all functions resizing metadata blocks now return the object
+ *   untouched if memory allocation fails, whereas previously the
+ *   handling varied and was more or less undefined
+ * - all functions accepting a filename now take UTF-8 encoded filenames
+ *   on Windows instead of filenames in the current codepage
+ *
+ * Furthermore, there have been the following additions
+ * - the functions FLAC__stream_encoder_set_limit_min_bitrate,
+ *   FLAC__stream_encoder_get_limit_min_bitrate,
+ *   FLAC::encoder::file::set_limit_min_bitrate() and
+ *   FLAC::encoder::file::get_limit_min_bitrate() have been added
+ * - Added FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA to the
+ *   FLAC__StreamDecoderErrorStatus enum
+ *
+ * \section porting_1_3_4_to_1_4_0_breaking Breaking changes
+ *
+ * The function \b get_client_data_from_decoder was added in FLAC 1.3.3
+ * but did not follow the API naming convention and was not properly
+ * exported. The function is now renamed and properly integrated as
+ * FLAC__stream_decoder_get_client_data
+ *
+ * To accomodate encoding and decoding 32-bit int PCM, some data types
+ * in the \b FLAC__frame struct were changed. Specifically, warmup
+ * in both the FLAC__Subframe_Fixed struc and the FLAC__Subframe_LPC
+ * struct is changed from FLAC__int32 to FLAC__int64. Also, value
+ * in the FLAC__Subframe_Constant is changed from FLAC__int32 to
+ * FLAC__int64. Finally, in FLAC__Subframe_Verbatim struct data is
+ * changes from a FLAC__int32 array to a union containing a FLAC__int32
+ * array and a FLAC__int64 array. Also, a new member is added,
+ * data_type, which clarifies whether the FLAC__int32 or FLAC__int64
+ * array is in use.
+ *
+ * Furthermore, the following functions now return the object untouched
+ * if memory allocation fails, whereas previously the handling varied
+ * and was more or less undefined
+ *
+ * - FLAC__metadata_object_seektable_resize_points
+ * - FLAC__metadata_object_vorbiscomment_resize_comments
+ * - FLAC__metadata_object_cuesheet_track_resize_indices
+ * - FLAC__metadata_object_cuesheet_resize_tracks
+ *
+ * The last breaking change is that all API functions taking a filename
+ * as an argument now, on Windows, must be supplied with that filename
+ * in the UTF-8 character encoding instead of using the current code
+ * page. libFLAC internally translates these UTF-8 encoded filenames to
+ * an appropriate representation to use with _wfopen. On all other
+ * systems, filename is passed to fopen without any translation, as it
+ * in libFLAC 1.3.4 and earlier.
+ *
+ * \section porting_1_3_4_to_1_4_0_additions Additions
+ *
+ * To aid in creating properly streamable FLAC files, a set of functions
+ * was added to make it possible to enfore a minimum bitrate to files
+ * created through libFLAC's stream_encoder.h interface. With this
+ * function enabled the resulting FLAC files have a minimum bitrate of
+ * 1bit/sample independent of the number of channels, i.e. 48kbit/s for
+ * 48kHz. This can be beneficial for streaming, as very low bitrates for
+ * silent sections compressed with 'constant' subframes can result in a
+ * bitrate of 1kbit/s, creating problems with clients that aren't aware
+ * of this possibility and buffer too much data.
+ *
+ * Finally, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA was added to
+ * the FLAC__StreamDecoderErrorStatus enum to signal that the decoder
+ * encountered unreadable metadata.
+ *
  */
 
 /** \defgroup flac FLAC C API
--- a/sys/src/cmd/audio/libFLAC/FLAC/assert.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/assert.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/FLAC/callback.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/callback.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2004-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/FLAC/export.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/export.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,7 +36,7 @@
 /** \file include/FLAC/export.h
  *
  *  \brief
- *  This module contains #defines and symbols for exporting function
+ *  This module contains \#defines and symbols for exporting function
  *  calls, and providing version information and compiled-in features.
  *
  *  See the \link flac_export export \endlink module.
@@ -46,7 +46,7 @@
  *  \ingroup flac
  *
  *  \brief
- *  This module contains #defines and symbols for exporting function
+ *  This module contains \#defines and symbols for exporting function
  *  calls, and providing version information and compiled-in features.
  *
  *  If you are compiling with MSVC and will link to the static library
@@ -56,15 +56,22 @@
  * \{
  */
 
-#if defined(FLAC__NO_DLL)
-#define FLAC_API
+/* This has grown quite complicated. FLAC__NO_DLL is used by MSVC sln
+ * files and CMake, which build either static or shared. autotools can
+ * build static, shared or **both**. Therefore, DLL_EXPORT, which is set
+ * by libtool, must override FLAC__NO_DLL on building shared components
+ */
+#if defined(_WIN32)
 
-#elif defined(_MSC_VER)
+#if defined(FLAC__NO_DLL) && !(defined(DLL_EXPORT))
+#define FLAC_API
+#else
 #ifdef FLAC_API_EXPORTS
 #define	FLAC_API __declspec(dllexport)
 #else
 #define FLAC_API __declspec(dllimport)
 #endif
+#endif
 
 #elif defined(FLAC__USE_VISIBILITY_ATTR)
 #define FLAC_API __attribute__ ((visibility ("default")))
@@ -74,12 +81,12 @@
 
 #endif
 
-/** These #defines will mirror the libtool-based library version number, see
+/** These \#defines will mirror the libtool-based library version number, see
  * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
  */
-#define FLAC_API_VERSION_CURRENT 11
+#define FLAC_API_VERSION_CURRENT 12
 #define FLAC_API_VERSION_REVISION 0 /**< see above */
-#define FLAC_API_VERSION_AGE 3 /**< see above */
+#define FLAC_API_VERSION_AGE 0 /**< see above */
 
 #ifdef __cplusplus
 extern "C" {
--- a/sys/src/cmd/audio/libFLAC/FLAC/format.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/format.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -113,19 +113,17 @@
 
 /** The maximum sample resolution permitted by libFLAC.
  *
- * \warning
  * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format.  However,
- * the reference encoder/decoder is currently limited to 24 bits because
- * of prevalent 32-bit math, so make sure and use this value when
- * appropriate.
+ * the reference encoder/decoder used to be limited to 24 bits. This
+ * value was used to signal that limit.
  */
-#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u)
+#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (32u)
 
 /** The maximum sample rate permitted by the format.  The value is
  *  ((2 ^ 16) - 1) * 10; see <A HREF="../format.html">FLAC format</A>
  *  as to why.
  */
-#define FLAC__MAX_SAMPLE_RATE (655350u)
+#define FLAC__MAX_SAMPLE_RATE (1048575u)
 
 /** The maximum LPC order permitted by the format. */
 #define FLAC__MAX_LPC_ORDER (32u)
@@ -282,14 +280,24 @@
 /** CONSTANT subframe.  (c.f. <A HREF="../format.html#subframe_constant">format specification</A>)
  */
 typedef struct {
-	FLAC__int32 value; /**< The constant signal value. */
+	FLAC__int64 value; /**< The constant signal value. */
 } FLAC__Subframe_Constant;
 
+/** An enumeration of the possible verbatim subframe data types. */
+typedef enum {
+	FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32, /**< verbatim subframe has 32-bit int */
+	FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64 /**< verbatim subframe has 64-bit int */
+} FLAC__VerbatimSubframeDataType;
 
+
 /** VERBATIM subframe.  (c.f. <A HREF="../format.html#subframe_verbatim">format specification</A>)
  */
 typedef struct {
-	const FLAC__int32 *data; /**< A pointer to verbatim signal. */
+	union {
+		const FLAC__int32 *int32; /**< A FLAC__int32 pointer to verbatim signal. */
+		const FLAC__int64 *int64; /**< A FLAC__int64 pointer to verbatim signal. */
+	} data;
+	FLAC__VerbatimSubframeDataType data_type;
 } FLAC__Subframe_Verbatim;
 
 
@@ -302,7 +310,7 @@
 	uint32_t order;
 	/**< The polynomial order. */
 
-	FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER];
+	FLAC__int64 warmup[FLAC__MAX_FIXED_ORDER];
 	/**< Warmup samples to prime the predictor, length == order. */
 
 	const FLAC__int32 *residual;
@@ -328,7 +336,7 @@
 	FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
 	/**< FIR filter coefficients. */
 
-	FLAC__int32 warmup[FLAC__MAX_LPC_ORDER];
+	FLAC__int64 warmup[FLAC__MAX_LPC_ORDER];
 	/**< Warmup samples to prime the predictor, length == order. */
 
 	const FLAC__int32 *residual;
@@ -831,7 +839,7 @@
 
 /** FLAC metadata block structure.  (c.f. <A HREF="../format.html#metadata_block">format specification</A>)
  */
-typedef struct {
+typedef struct FLAC__StreamMetadata {
 	FLAC__MetadataType type;
 	/**< The type of the metadata block; used determine which member of the
 	 * \a data union to dereference.  If type >= FLAC__METADATA_TYPE_UNDEFINED
--- a/sys/src/cmd/audio/libFLAC/FLAC/metadata.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/metadata.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -134,6 +134,11 @@
  *  STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring
  *  only a filename.
  *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
+ *
  *  They try to skip any ID3v2 tag at the head of the file.
  *
  * \{
@@ -387,6 +392,11 @@
 /** Initialize the iterator to point to the first metadata block in the
  *  given FLAC file.
  *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
+ *
  * \param iterator             A pointer to an existing iterator.
  * \param filename             The path to the FLAC file.
  * \param read_only            If \c true, the FLAC file will be opened
@@ -820,6 +830,11 @@
 
 /** Read all metadata from a FLAC file into the chain.
  *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
+ *
  * \param chain    A pointer to an existing chain.
  * \param filename The path to the FLAC file to read.
  * \assert
@@ -834,6 +849,11 @@
 
 /** Read all metadata from an Ogg FLAC file into the chain.
  *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
+ *
  * \note Ogg FLAC metadata data writing is not supported yet and
  * FLAC__metadata_chain_write() will fail.
  *
@@ -1378,7 +1398,8 @@
 /** Resize the seekpoint array.
  *
  *  If the size shrinks, elements will truncated; if it grows, new placeholder
- *  points will be added to the end.
+ *  points will be added to the end. If this function returns false, the
+ *  object is left untouched.
  *
  * \param object          A pointer to an existing SEEKTABLE object.
  * \param new_num_points  The desired length of the array; may be \c 0.
@@ -1591,7 +1612,8 @@
 /** Resize the comment array.
  *
  *  If the size shrinks, elements will truncated; if it grows, new empty
- *  fields will be added to the end.
+ *  fields will be added to the end.  If this function returns false, the
+ *  object is left untouched.
  *
  * \param object            A pointer to an existing VORBIS_COMMENT object.
  * \param new_num_comments  The desired length of the array; may be \c 0.
@@ -1871,7 +1893,8 @@
 /** Resize a track's index point array.
  *
  *  If the size shrinks, elements will truncated; if it grows, new blank
- *  indices will be added to the end.
+ *  indices will be added to the end. If this function returns false, the
+ *  track object is left untouched.
  *
  * \param object           A pointer to an existing CUESHEET object.
  * \param track_num        The index of the track to modify.  NOTE: this is not
@@ -1957,7 +1980,8 @@
 /** Resize the track array.
  *
  *  If the size shrinks, elements will truncated; if it grows, new blank
- *  tracks will be added to the end.
+ *  tracks will be added to the end.  If this function returns false, the
+ *  object is left untouched.
  *
  * \param object            A pointer to an existing CUESHEET object.
  * \param new_num_tracks    The desired length of the array; may be \c 0.
--- a/sys/src/cmd/audio/libFLAC/FLAC/ordinals.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/ordinals.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/FLAC/stream_decoder.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/stream_decoder.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -422,7 +422,11 @@
  *  could be because the decoder encountered a valid frame made by a future
  *  version of the encoder which it cannot parse, or because of a false
  *  sync making it appear as though an encountered frame was generated by
- *  a future encoder.
+ *  a future encoder. \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA is
+ *  caused by finding data that doesn't fit a metadata block (too large
+ *  or too small) or finding inconsistencies in the metadata, for example
+ *  a PICTURE block with an image that exceeds the size of the metadata
+ *  block.
  */
 typedef enum {
 
@@ -435,9 +439,12 @@
 	FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH,
 	/**< The frame's data did not match the CRC in the footer. */
 
-	FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
+	FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM,
 	/**< The decoder encountered reserved fields in use in the stream. */
 
+	FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA
+	/**< The decoder encountered a corrupted metadata block. */
+
 } FLAC__StreamDecoderErrorStatus;
 
 /** Maps a FLAC__StreamDecoderErrorStatus to a C string.
@@ -1006,6 +1013,16 @@
  */
 FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position);
 
+/** Return client_data from decoder.
+ *  The data pointed to by the pointer should not be modified.
+ *
+ * \param  decoder  A decoder instance.
+ * \retval const void *
+ *    The callee's client data set through FLAC__stream_decoder_init_*().
+ *    Do not modify the contents.
+ */
+FLAC_API const void *FLAC__stream_decoder_get_client_data(FLAC__StreamDecoder *decoder);
+
 /** Initialize the decoder instance to decode native FLAC streams.
  *
  *  This flavor of initialization sets up the decoder to decode from a
@@ -1263,11 +1280,15 @@
 /** Initialize the decoder instance to decode native FLAC files.
  *
  *  This flavor of initialization sets up the decoder to decode from a plain
- *  native FLAC file.  If POSIX fopen() semantics are not sufficient, (for
- *  example, with Unicode filenames on Windows), you must use
- *  FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream()
+ *  native FLAC file.  If POSIX fopen() semantics are not sufficient, you must
+ *  use FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream()
  *  and provide callbacks for the I/O.
  *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
+ *
  *  This function should be called after FLAC__stream_decoder_new() and
  *  FLAC__stream_decoder_set_*() but before any of the
  *  FLAC__stream_decoder_process_*() functions.  Will set and return the
@@ -1305,10 +1326,14 @@
 /** Initialize the decoder instance to decode Ogg FLAC files.
  *
  *  This flavor of initialization sets up the decoder to decode from a plain
- *  Ogg FLAC file.  If POSIX fopen() semantics are not sufficient, (for
- *  example, with Unicode filenames on Windows), you must use
+ *  Ogg FLAC file.  If POSIX fopen() semantics are not sufficient, you must use
  *  FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream()
  *  and provide callbacks for the I/O.
+ *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
  *
  *  This function should be called after FLAC__stream_decoder_new() and
  *  FLAC__stream_decoder_set_*() but before any of the
--- a/sys/src/cmd/audio/libFLAC/FLAC/stream_encoder.h
+++ b/sys/src/cmd/audio/libFLAC/FLAC/stream_encoder.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -991,10 +991,6 @@
  *  coefficients, or \c 0 to let the encoder select it based on the
  *  blocksize.
  *
- * \note
- * In the current implementation, qlp_coeff_precision + bits_per_sample must
- * be less than 32.
- *
  * \default \c 0
  * \param  encoder  An encoder instance to set.
  * \param  value    See above.
@@ -1202,6 +1198,24 @@
  */
 FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, uint32_t num_blocks);
 
+/** Set to \c true to make the encoder not output frames which contain
+ *  only constant subframes. This is beneficial for streaming
+ *  applications: very small frames can cause problems with buffering
+ *  as bitrates can drop as low 1kbit/s for CDDA audio encoded within
+ *  subset. The minimum bitrate for a FLAC file encoded with this
+ *  function used is raised to 1bit/sample (i.e. 48kbit/s for 48kHz
+ *  material).
+ *
+ * \default \c false
+ * \param  encoder  An encoder instance to set.
+ * \param  value    Flag value (see above).
+ * \assert
+ *    \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ *    \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_limit_min_bitrate(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
 /** Get the current encoder state.
  *
  * \param  encoder  An encoder instance to query.
@@ -1429,6 +1443,16 @@
  */
 FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder);
 
+/** Get the "limit_min_bitrate" flag.
+ *
+ * \param  encoder  An encoder instance to query.
+ * \assert
+ *    \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ *    See FLAC__stream_encoder_set_limit_min_bitrate().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder);
+
 /** Initialize the encoder instance to encode native FLAC streams.
  *
  *  This flavor of initialization sets up the encoder to encode to a
@@ -1633,11 +1657,15 @@
 /** Initialize the encoder instance to encode native FLAC files.
  *
  *  This flavor of initialization sets up the encoder to encode to a plain
- *  FLAC file.  If POSIX fopen() semantics are not sufficient (for example,
- *  with Unicode filenames on Windows), you must use
+ *  FLAC file.  If POSIX fopen() semantics are not sufficient you must use
  *  FLAC__stream_encoder_init_FILE(), or FLAC__stream_encoder_init_stream()
  *  and provide callbacks for the I/O.
  *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
+ *
  *  This function should be called after FLAC__stream_encoder_new() and
  *  FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
  *  or FLAC__stream_encoder_process_interleaved().
@@ -1665,10 +1693,14 @@
 /** Initialize the encoder instance to encode Ogg FLAC files.
  *
  *  This flavor of initialization sets up the encoder to encode to a plain
- *  Ogg FLAC file.  If POSIX fopen() semantics are not sufficient (for example,
- *  with Unicode filenames on Windows), you must use
+ *  Ogg FLAC file.  If POSIX fopen() semantics are not sufficient, you must use
  *  FLAC__stream_encoder_init_ogg_FILE(), or FLAC__stream_encoder_init_ogg_stream()
  *  and provide callbacks for the I/O.
+ *
+ *  On Windows, filename must be a UTF-8 encoded filename, which libFLAC
+ *  internally translates to an appropriate representation to use with
+ *  _wfopen. On all other systems, filename is passed to fopen without
+ *  any translation.
  *
  *  This function should be called after FLAC__stream_encoder_new() and
  *  FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
--- a/sys/src/cmd/audio/libFLAC/bitmath.c
+++ b/sys/src/cmd/audio/libFLAC/bitmath.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/bitreader.c
+++ b/sys/src/cmd/audio/libFLAC/bitreader.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2018  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -111,6 +111,9 @@
 	uint32_t read_crc16; /* the running frame CRC */
 	uint32_t crc16_offset; /* the number of words in the current buffer that should not be CRC'd */
 	uint32_t crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
+	FLAC__bool read_limit_set; /* whether reads are limited */
+	uint32_t read_limit; /* the remaining size of what can be read */
+	uint32_t last_seen_framesync; /* the location of the last seen framesync, if it is in the buffer, in bits from front of buffer */
 	FLAC__BitReaderReadCallback read_callback;
 	void *client_data;
 };
@@ -155,7 +158,14 @@
 	uint32_t start, end;
 	size_t bytes;
 	FLAC__byte *target;
+#if WORDS_BIGENDIAN
+#else
+	brword preswap_backup;
+#endif
 
+	/* invalidate last seen framesync */
+	br->last_seen_framesync = -1;
+
 	/* first shift the unconsumed buffer data toward the front as much as possible */
 	if(br->consumed_words > 0) {
 		crc16_update_block_(br); /* CRC consumed words */
@@ -186,6 +196,7 @@
 	 */
 #if WORDS_BIGENDIAN
 #else
+	preswap_backup = br->buffer[br->words];
 	if(br->bytes)
 		br->buffer[br->words] = SWAP_BE_WORD_TO_HOST(br->buffer[br->words]);
 #endif
@@ -198,8 +209,16 @@
 	 */
 
 	/* read in the data; note that the callback may return a smaller number of bytes */
-	if(!br->read_callback(target, &bytes, br->client_data))
+	if(!br->read_callback(target, &bytes, br->client_data)){
+		/* Despite the read callback failing, the data in the target
+		 * might be used later, when the buffer is rewound. Therefore
+		 * we revert the swap that was just done */
+#if WORDS_BIGENDIAN
+#else
+		br->buffer[br->words] = preswap_backup;
+#endif
 		return false;
+	}
 
 	/* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client:
 	 *   bitstream :  11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
@@ -275,6 +294,9 @@
 		return false;
 	br->read_callback = rcb;
 	br->client_data = cd;
+	br->read_limit_set = false;
+	br->read_limit = -1;
+	br->last_seen_framesync = -1;
 
 	return true;
 }
@@ -291,6 +313,9 @@
 	br->consumed_words = br->consumed_bits = 0;
 	br->read_callback = 0;
 	br->client_data = 0;
+	br->read_limit_set = false;
+	br->read_limit = -1;
+	br->last_seen_framesync = -1;
 }
 
 FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br)
@@ -297,9 +322,30 @@
 {
 	br->words = br->bytes = 0;
 	br->consumed_words = br->consumed_bits = 0;
+	br->read_limit_set = false;
+	br->read_limit = -1;
+	br->last_seen_framesync = -1;
 	return true;
 }
 
+void FLAC__bitreader_set_framesync_location(FLAC__BitReader *br)
+{
+	br->last_seen_framesync = br->consumed_words * FLAC__BYTES_PER_WORD + br->consumed_bits / 8;
+}
+
+FLAC__bool FLAC__bitreader_rewind_to_after_last_seen_framesync(FLAC__BitReader *br)
+{
+	if(br->last_seen_framesync == (uint32_t)-1) {
+		br->consumed_words = br->consumed_bits = 0;
+		return false;
+	}
+	else {
+		br->consumed_words = (br->last_seen_framesync + 1) / FLAC__BYTES_PER_WORD;
+		br->consumed_bits  = ((br->last_seen_framesync + 1) % FLAC__BYTES_PER_WORD) * 8;
+		return true;
+	}
+}
+
 void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out)
 {
 	uint32_t i, j;
@@ -376,6 +422,28 @@
 	return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits;
 }
 
+void FLAC__bitreader_set_limit(FLAC__BitReader *br, uint32_t limit)
+{
+	br->read_limit = limit;
+	br->read_limit_set = true;
+}
+
+void FLAC__bitreader_remove_limit(FLAC__BitReader *br)
+{
+	br->read_limit_set = false;
+	br->read_limit = -1;
+}
+
+uint32_t FLAC__bitreader_limit_remaining(FLAC__BitReader *br)
+{
+	FLAC__ASSERT(br->read_limit_set);
+	return br->read_limit;
+}
+void FLAC__bitreader_limit_invalidate(FLAC__BitReader *br)
+{
+	br->read_limit = -1;
+}
+
 FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits)
 {
 	FLAC__ASSERT(0 != br);
@@ -393,6 +461,15 @@
 		return true;
 	}
 
+	if(br->read_limit_set && br->read_limit < (uint32_t)-1){
+		if(br->read_limit < bits) {
+			br->read_limit = -1;
+			return false;
+		}
+		else
+			br->read_limit -= bits;
+	}
+
 	while((br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits < bits) {
 		if(!bitreader_read_from_client_(br))
 			return false;
@@ -465,7 +542,7 @@
 		return false;
 	/* sign-extend *val assuming it is currently bits wide. */
 	/* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */
-	mask = bits >= 33 ? 0 : 1u << (bits - 1);
+	mask = bits >= 33 ? 0 : 1lu << (bits - 1);
 	*val = (uval ^ mask) - mask;
 	return true;
 }
@@ -491,6 +568,19 @@
 	return true;
 }
 
+FLAC__bool FLAC__bitreader_read_raw_int64(FLAC__BitReader *br, FLAC__int64 *val, uint32_t bits)
+{
+	FLAC__uint64 uval, mask;
+	/* OPT: inline raw uint64 code here, or make into a macro if possible in the .h file */
+	if (bits < 1 || ! FLAC__bitreader_read_raw_uint64(br, &uval, bits))
+		return false;
+	/* sign-extend *val assuming it is currently bits wide. */
+	/* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */
+	mask = bits >= 65 ? 0 : 1llu << (bits - 1);
+	*val = (uval ^ mask) - mask;
+	return true;
+}
+
 inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val)
 {
 	FLAC__uint32 x8, x32 = 0;
@@ -559,6 +649,13 @@
 	FLAC__ASSERT(0 != br->buffer);
 	FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br));
 
+	if(br->read_limit_set && br->read_limit < (uint32_t)-1){
+		if(br->read_limit < nvals*8){
+			br->read_limit = -1;
+			return false;
+		}
+	}
+
 	/* step 1: skip over partial head word to get word aligned */
 	while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */
 		if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
@@ -567,11 +664,14 @@
 	}
 	if(0 == nvals)
 		return true;
+
 	/* step 2: skip whole words in chunks */
 	while(nvals >= FLAC__BYTES_PER_WORD) {
 		if(br->consumed_words < br->words) {
 			br->consumed_words++;
 			nvals -= FLAC__BYTES_PER_WORD;
+			if(br->read_limit_set)
+				br->read_limit -= FLAC__BITS_PER_WORD;
 		}
 		else if(!bitreader_read_from_client_(br))
 			return false;
@@ -594,6 +694,13 @@
 	FLAC__ASSERT(0 != br->buffer);
 	FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br));
 
+	if(br->read_limit_set && br->read_limit < (uint32_t)-1){
+		if(br->read_limit < nvals*8){
+			br->read_limit = -1;
+			return false;
+		}
+	}
+
 	/* step 1: read from partial head word to get word aligned */
 	while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */
 		if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
@@ -627,6 +734,8 @@
 #endif
 			val += FLAC__BYTES_PER_WORD;
 			nvals -= FLAC__BYTES_PER_WORD;
+			if(br->read_limit_set)
+				br->read_limit -= FLAC__BITS_PER_WORD;
 		}
 		else if(!bitreader_read_from_client_(br))
 			return false;
@@ -721,6 +830,7 @@
 }
 #endif
 
+#if 0 /* unused */
 FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint32_t parameter)
 {
 	FLAC__uint32 lsbs = 0, msbs = 0;
@@ -747,6 +857,7 @@
 
 	return true;
 }
+#endif
 
 /* this is by far the most heavily used reader call.  it ain't pretty but it's fast */
 FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter)
@@ -754,7 +865,7 @@
 	/* try and get br->consumed_words and br->consumed_bits into register;
 	 * must remember to flush them back to *br before calling other
 	 * bitreader functions that use them, and before returning */
-	uint32_t cwords, words, lsbs, msbs, x, y;
+	uint32_t cwords, words, lsbs, msbs, x, y, limit;
 	uint32_t ucbits; /* keep track of the number of unconsumed bits in word */
 	brword b;
 	int *val, *end;
@@ -766,6 +877,8 @@
 	FLAC__ASSERT(parameter < 32);
 	/* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */
 
+	limit = UINT32_MAX >> parameter; /* Maximal msbs that can occur with residual bounded to int32_t */
+
 	val = vals;
 	end = vals + nvals;
 
@@ -774,7 +887,8 @@
 			/* read the unary MSBs and end bit */
 			if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
 				return false;
-
+			/* Checking limit here would be overzealous: coding UINT32_MAX
+			 * with parameter == 0 would take 4GiB */
 			*val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1);
 		}
 
@@ -814,6 +928,9 @@
 		b <<= 1; /* account for stop bit */
 		ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD;
 		msbs = x;
+
+		if(x > limit)
+			return false;
 
 		/* read the binary LSBs */
 		x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit uint32_t */
--- a/sys/src/cmd/audio/libFLAC/bitwriter.c
+++ b/sys/src/cmd/audio/libFLAC/bitwriter.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,7 +38,9 @@
 #include <string.h>
 #include "private/bitwriter.h"
 #include "private/crc.h"
+#include "private/format.h"
 #include "private/macros.h"
+#include "private/stream_encoder.h"
 #include "FLAC/assert.h"
 #include "share/alloc.h"
 #include "share/compat.h"
@@ -116,6 +118,13 @@
 	if(bw->capacity >= new_capacity)
 		return true;
 
+	if(new_capacity * sizeof(bwword) > (1u << FLAC__STREAM_METADATA_LENGTH_LEN))
+		/* Requested new capacity is larger than the largest possible metadata block,
+		 * which is also larger than the largest sane framesize. That means something
+		 * went very wrong somewhere and previous checks failed.
+		 * To prevent chrashing, give up */
+		return false;
+
 	/* round up capacity increase to the nearest FLAC__BITWRITER_DEFAULT_INCREMENT */
 	if((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT)
 		new_capacity += FLAC__BITWRITER_DEFAULT_INCREMENT - ((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT);
@@ -124,7 +133,7 @@
 	FLAC__ASSERT(new_capacity > bw->capacity);
 	FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD));
 
-	new_buffer = safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity);
+	new_buffer = safe_realloc_nofree_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity);
 	if(new_buffer == 0)
 		return false;
 	bw->buffer = new_buffer;
@@ -390,6 +399,15 @@
 		return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits);
 }
 
+inline FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits)
+{
+	FLAC__uint64 uval = val;
+	/* zero-out unused bits */
+	if(bits < 64)
+		uval &= (~(UINT64_MAX << bits));
+	return FLAC__bitwriter_write_raw_uint64(bw, uval, bits);
+}
+
 inline FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val)
 {
 	/* this doesn't need to be that fast as currently it is only used for vorbis comments */
@@ -881,5 +899,6 @@
 extern FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits);
 extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits);
 extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits);
+extern FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits);
 extern FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val);
 extern FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals);
--- a/sys/src/cmd/audio/libFLAC/crc.c
+++ b/sys/src/cmd/audio/libFLAC/crc.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2018  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/fixed.c
+++ b/sys/src/cmd/audio/libFLAC/fixed.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -47,6 +47,11 @@
 #endif
 #define local_abs(x) ((uint32_t)((x)<0? -(x) : (x)))
 
+#ifdef local_abs64
+#undef local_abs64
+#endif
+#define local_abs64(x) ((uint64_t)((x)<0? -(x) : (x)))
+
 #ifdef FLAC__INTEGER_ONLY_LIBRARY
 /* rbps stands for residual bits per sample
  *
@@ -219,15 +224,23 @@
 uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
 #endif
 {
+	FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
+	uint32_t order;
+#if 0
+	/* This code has been around a long time, and was written when compilers weren't able
+	 * to vectorize code. These days, compilers are better in optimizing the next block
+	 * which is also much more readable
+	 */
 	FLAC__int32 last_error_0 = data[-1];
 	FLAC__int32 last_error_1 = data[-1] - data[-2];
 	FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
 	FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
 	FLAC__int32 error, save;
-	FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
-	uint32_t i, order;
-
-	for(i = 0; i < data_len; i++) {
+	/* total_error_* are 64-bits to avoid overflow when encoding
+	 * erratic signals when the bits-per-sample and blocksize are
+	 * large.
+	 */
+	for(uint32_t i = 0; i < data_len; i++) {
 		error  = data[i]     ; total_error_0 += local_abs(error);                      save = error;
 		error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
 		error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
@@ -234,14 +247,25 @@
 		error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
 		error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
 	}
+#else
+	for(int i = 0; i < (int)data_len; i++) {
+		total_error_0 += local_abs(data[i]);
+		total_error_1 += local_abs(data[i] - data[i-1]);
+		total_error_2 += local_abs(data[i] - 2 * data[i-1] + data[i-2]);
+		total_error_3 += local_abs(data[i] - 3 * data[i-1] + 3 * data[i-2] - data[i-3]);
+		total_error_4 += local_abs(data[i] - 4 * data[i-1] + 6 * data[i-2] - 4 * data[i-3] + data[i-4]);
+	}
+#endif
 
-	if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
+
+	/* prefer lower order */
+	if(total_error_0 <= flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
 		order = 0;
-	else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
+	else if(total_error_1 <= flac_min(flac_min(total_error_2, total_error_3), total_error_4))
 		order = 1;
-	else if(total_error_2 < flac_min(total_error_3, total_error_4))
+	else if(total_error_2 <= flac_min(total_error_3, total_error_4))
 		order = 2;
-	else if(total_error_3 < total_error_4)
+	else if(total_error_3 <= total_error_4)
 		order = 3;
 	else
 		order = 4;
@@ -277,33 +301,25 @@
 uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
 #endif
 {
-	FLAC__int32 last_error_0 = data[-1];
-	FLAC__int32 last_error_1 = data[-1] - data[-2];
-	FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
-	FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
-	FLAC__int32 error, save;
-	/* total_error_* are 64-bits to avoid overflow when encoding
-	 * erratic signals when the bits-per-sample and blocksize are
-	 * large.
-	 */
 	FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
-	uint32_t i, order;
+	uint32_t order;
 
-	for(i = 0; i < data_len; i++) {
-		error  = data[i]     ; total_error_0 += local_abs(error);                      save = error;
-		error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
-		error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
-		error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
-		error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
+	for(int i = 0; i < (int)data_len; i++) {
+		total_error_0 += local_abs(data[i]);
+		total_error_1 += local_abs(data[i] - data[i-1]);
+		total_error_2 += local_abs(data[i] - 2 * data[i-1] + data[i-2]);
+		total_error_3 += local_abs(data[i] - 3 * data[i-1] + 3 * data[i-2] - data[i-3]);
+		total_error_4 += local_abs(data[i] - 4 * data[i-1] + 6 * data[i-2] - 4 * data[i-3] + data[i-4]);
 	}
 
-	if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
+	/* prefer lower order */
+	if(total_error_0 <= flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
 		order = 0;
-	else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
+	else if(total_error_1 <= flac_min(flac_min(total_error_2, total_error_3), total_error_4))
 		order = 1;
-	else if(total_error_2 < flac_min(total_error_3, total_error_4))
+	else if(total_error_2 <= flac_min(total_error_3, total_error_4))
 		order = 2;
-	else if(total_error_3 < total_error_4)
+	else if(total_error_3 <= total_error_4)
 		order = 3;
 	else
 		order = 4;
@@ -333,6 +349,119 @@
 	return order;
 }
 
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+#define CHECK_ORDER_IS_VALID(macro_order)		\
+if(order_##macro_order##_is_valid && total_error_##macro_order < smallest_error) { \
+	order = macro_order;				\
+	smallest_error = total_error_##macro_order ;	\
+	residual_bits_per_sample[ macro_order ] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); \
+}							\
+else							\
+	residual_bits_per_sample[ macro_order ] = 34.0f;
+#else
+#define CHECK_ORDER_IS_VALID(macro_order)		\
+if(order_##macro_order##_is_valid && total_error_##macro_order < smallest_error) { \
+	order = macro_order;				\
+	smallest_error = total_error_##macro_order ;	\
+	residual_bits_per_sample[ macro_order ] = (total_error_##macro_order > 0) ? local__compute_rbps_wide_integerized(total_error_##macro_order, data_len) : 0; \
+}							\
+else							\
+	residual_bits_per_sample[ macro_order ] = 34 * FLAC__FP_ONE;
+#endif
+
+
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#else
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#endif
+{
+	FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0, smallest_error = UINT64_MAX;
+	FLAC__uint64 error_0, error_1, error_2, error_3, error_4;
+	FLAC__bool order_0_is_valid = true, order_1_is_valid = true, order_2_is_valid = true, order_3_is_valid = true, order_4_is_valid = true;
+	uint32_t order = 0;
+
+	for(int i = 0; i < (int)data_len; i++) {
+		error_0 = local_abs64((FLAC__int64)data[i]);
+		error_1 = (i > 0) ? local_abs64((FLAC__int64)data[i] - data[i-1]) : 0 ;
+		error_2 = (i > 1) ? local_abs64((FLAC__int64)data[i] - 2 * (FLAC__int64)data[i-1] + data[i-2]) : 0;
+		error_3 = (i > 2) ? local_abs64((FLAC__int64)data[i] - 3 * (FLAC__int64)data[i-1] + 3 * (FLAC__int64)data[i-2] - data[i-3]) : 0;
+		error_4 = (i > 3) ? local_abs64((FLAC__int64)data[i] - 4 * (FLAC__int64)data[i-1] + 6 * (FLAC__int64)data[i-2] - 4 * (FLAC__int64)data[i-3] + data[i-4]) : 0;
+
+		total_error_0 += error_0;
+		total_error_1 += error_1;
+		total_error_2 += error_2;
+		total_error_3 += error_3;
+		total_error_4 += error_4;
+
+		/* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+		if(error_0 > INT32_MAX)
+			order_0_is_valid = false;
+		if(error_1 > INT32_MAX)
+			order_1_is_valid = false;
+		if(error_2 > INT32_MAX)
+			order_2_is_valid = false;
+		if(error_3 > INT32_MAX)
+			order_3_is_valid = false;
+		if(error_4 > INT32_MAX)
+			order_4_is_valid = false;
+	}
+
+	CHECK_ORDER_IS_VALID(0);
+	CHECK_ORDER_IS_VALID(1);
+	CHECK_ORDER_IS_VALID(2);
+	CHECK_ORDER_IS_VALID(3);
+	CHECK_ORDER_IS_VALID(4);
+
+	return order;
+}
+
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#else
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#endif
+{
+	FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0, smallest_error = UINT64_MAX;
+	FLAC__uint64 error_0, error_1, error_2, error_3, error_4;
+	FLAC__bool order_0_is_valid = true, order_1_is_valid = true, order_2_is_valid = true, order_3_is_valid = true, order_4_is_valid = true;
+	uint32_t order = 0;
+
+	for(int i = 0; i < (int)data_len; i++) {
+		error_0 = local_abs64(data[i]);
+		error_1 = (i > 0) ? local_abs64(data[i] - data[i-1]) : 0 ;
+		error_2 = (i > 1) ? local_abs64(data[i] - 2 * data[i-1] + data[i-2]) : 0;
+		error_3 = (i > 2) ? local_abs64(data[i] - 3 * data[i-1] + 3 * data[i-2] - data[i-3]) : 0;
+		error_4 = (i > 3) ? local_abs64(data[i] - 4 * data[i-1] + 6 * data[i-2] - 4 * data[i-3] + data[i-4]) : 0;
+
+		total_error_0 += error_0;
+		total_error_1 += error_1;
+		total_error_2 += error_2;
+		total_error_3 += error_3;
+		total_error_4 += error_4;
+
+		/* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+		if(error_0 > INT32_MAX)
+			order_0_is_valid = false;
+		if(error_1 > INT32_MAX)
+			order_1_is_valid = false;
+		if(error_2 > INT32_MAX)
+			order_2_is_valid = false;
+		if(error_3 > INT32_MAX)
+			order_3_is_valid = false;
+		if(error_4 > INT32_MAX)
+			order_4_is_valid = false;
+	}
+
+	CHECK_ORDER_IS_VALID(0);
+	CHECK_ORDER_IS_VALID(1);
+	CHECK_ORDER_IS_VALID(2);
+	CHECK_ORDER_IS_VALID(3);
+	CHECK_ORDER_IS_VALID(4);
+
+	return order;
+}
+
 void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[])
 {
 	const int idata_len = (int)data_len;
@@ -364,6 +493,76 @@
 	}
 }
 
+void FLAC__fixed_compute_residual_wide(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[])
+{
+	const int idata_len = (int)data_len;
+	int i;
+
+	switch(order) {
+		case 0:
+			FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
+			memcpy(residual, data, sizeof(residual[0])*data_len);
+			break;
+		case 1:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = (FLAC__int64)data[i] - data[i-1];
+			break;
+		case 2:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = (FLAC__int64)data[i] - 2*(FLAC__int64)data[i-1] + data[i-2];
+			break;
+		case 3:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = (FLAC__int64)data[i] - 3*(FLAC__int64)data[i-1] + 3*(FLAC__int64)data[i-2] - data[i-3];
+			break;
+		case 4:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = (FLAC__int64)data[i] - 4*(FLAC__int64)data[i-1] + 6*(FLAC__int64)data[i-2] - 4*(FLAC__int64)data[i-3] + data[i-4];
+			break;
+		default:
+			FLAC__ASSERT(0);
+	}
+}
+
+void FLAC__fixed_compute_residual_wide_33bit(const FLAC__int64 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[])
+{
+	const int idata_len = (int)data_len;
+	int i;
+
+	switch(order) {
+		case 0:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = data[i];
+			break;
+		case 1:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = data[i] - data[i-1];
+			break;
+		case 2:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = data[i] - 2*data[i-1] + data[i-2];
+			break;
+		case 3:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3];
+			break;
+		case 4:
+			for(i = 0; i < idata_len; i++)
+				residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4];
+			break;
+		default:
+			FLAC__ASSERT(0);
+	}
+}
+
+#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
+/* The attribute below is to silence the undefined sanitizer of oss-fuzz.
+ * Because fuzzing feeds bogus predictors and residual samples to the
+ * decoder, having overflows in this section is unavoidable. Also,
+ * because the calculated values are audio path only, there is no
+ * potential for security problems */
+__attribute__((no_sanitize("signed-integer-overflow")))
+#endif
 void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[])
 {
 	int i, idata_len = (int)data_len;
@@ -388,6 +587,74 @@
 		case 4:
 			for(i = 0; i < idata_len; i++)
 				data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4];
+			break;
+		default:
+			FLAC__ASSERT(0);
+	}
+}
+
+void FLAC__fixed_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[])
+{
+	int i, idata_len = (int)data_len;
+
+	switch(order) {
+		case 0:
+			FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
+			memcpy(data, residual, sizeof(residual[0])*data_len);
+			break;
+		case 1:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + (FLAC__int64)data[i-1];
+			break;
+		case 2:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + 2*(FLAC__int64)data[i-1] - (FLAC__int64)data[i-2];
+			break;
+		case 3:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + 3*(FLAC__int64)data[i-1] - 3*(FLAC__int64)data[i-2] + (FLAC__int64)data[i-3];
+			break;
+		case 4:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + 4*(FLAC__int64)data[i-1] - 6*(FLAC__int64)data[i-2] + 4*(FLAC__int64)data[i-3] - (FLAC__int64)data[i-4];
+			break;
+		default:
+			FLAC__ASSERT(0);
+	}
+}
+
+#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
+/* The attribute below is to silence the undefined sanitizer of oss-fuzz.
+ * Because fuzzing feeds bogus predictors and residual samples to the
+ * decoder, having overflows in this section is unavoidable. Also,
+ * because the calculated values are audio path only, there is no
+ * potential for security problems */
+__attribute__((no_sanitize("signed-integer-overflow")))
+#endif
+void FLAC__fixed_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int64 data[])
+{
+	int i, idata_len = (int)data_len;
+
+	switch(order) {
+		case 0:
+			for(i = 0; i < idata_len; i++)
+				data[i] = residual[i];
+			break;
+		case 1:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + data[i-1];
+			break;
+		case 2:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + 2*data[i-1] - data[i-2];
+			break;
+		case 3:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3];
+			break;
+		case 4:
+			for(i = 0; i < idata_len; i++)
+				data[i] = (FLAC__int64)residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4];
 			break;
 		default:
 			FLAC__ASSERT(0);
--- a/sys/src/cmd/audio/libFLAC/float.c
+++ b/sys/src/cmd/audio/libFLAC/float.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2004-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/format.c
+++ b/sys/src/cmd/audio/libFLAC/format.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,11 +44,20 @@
 #include "private/format.h"
 #include "private/macros.h"
 
+#if (defined GIT_COMMIT_HASH && defined GIT_COMMIT_DATE)
+# ifdef GIT_COMMIT_TAG
+FLAC_API const char *FLAC__VERSION_STRING = GIT_COMMIT_TAG;
+FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " GIT_COMMIT_TAG " " GIT_COMMIT_DATE;
+# else
+FLAC_API const char *FLAC__VERSION_STRING = "git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE;
+FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE;
+# endif
+#else
 /* PACKAGE_VERSION should come from configure */
 FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION;
+FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20220909";
+#endif
 
-FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20220220";
-
 FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
 FLAC_API const uint32_t FLAC__STREAM_SYNC = 0x664C6143;
 FLAC_API const uint32_t FLAC__STREAM_SYNC_LEN = 32; /* bits */
@@ -218,12 +227,10 @@
 
 FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(uint32_t sample_rate)
 {
-	if(
-		!FLAC__format_sample_rate_is_valid(sample_rate) ||
-		(
-			sample_rate >= (1u << 16) &&
-			!(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
-		)
+	if( // sample rate is not subset if
+		!FLAC__format_sample_rate_is_valid(sample_rate) || // sample rate is invalid or
+		sample_rate >= ((1u << 16) * 10) || // sample rate is larger then or equal to 655360 or
+		(sample_rate >= (1u << 16) && sample_rate % 10 != 0) //sample rate is >= 65536 and not divisible by 10
 	) {
 		return false;
 	}
@@ -570,6 +577,11 @@
 	FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
 }
 
+#if defined(_MSC_VER)
+// silence three MSVC warnings 'result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)'
+#pragma warning ( disable : 4334 )
+#endif
+
 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order)
 {
 	FLAC__ASSERT(0 != object);
@@ -576,7 +588,7 @@
 
 	FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits));
 
-	if(object->capacity_by_order < max_partition_order) {
+	if(object->capacity_by_order < max_partition_order || object->parameters == NULL || object->raw_bits == NULL) {
 		if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(uint32_t)*(1 << max_partition_order))))
 			return false;
 		if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(uint32_t)*(1 << max_partition_order))))
@@ -587,3 +599,7 @@
 
 	return true;
 }
+
+#if defined(_MSC_VER)
+#pragma warning ( default : 4334 )
+#endif
--- a/sys/src/cmd/audio/libFLAC/lpc.c
+++ b/sys/src/cmd/audio/libFLAC/lpc.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,6 +35,7 @@
 #endif
 
 #include <math.h>
+#include <stdlib.h>
 
 #include "FLAC/assert.h"
 #include "FLAC/format.h"
@@ -42,6 +43,7 @@
 #include "private/bitmath.h"
 #include "private/lpc.h"
 #include "private/macros.h"
+
 #if !defined(NDEBUG) || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE
 #include <stdio.h>
 #endif
@@ -72,11 +74,46 @@
 		out[i] = in[i] * window[i];
 }
 
-void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[])
+void FLAC__lpc_window_data_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len)
 {
+	uint32_t i;
+	for(i = 0; i < data_len; i++)
+		out[i] = in[i] * window[i];
+}
+
+void FLAC__lpc_window_data_partial(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift)
+{
+	uint32_t i, j;
+	if((part_size + data_shift) < data_len){
+		for(i = 0; i < part_size; i++)
+			out[i] = in[data_shift+i] * window[i];
+		i = flac_min(i,data_len - part_size - data_shift);
+		for(j = data_len - part_size; j < data_len; i++, j++)
+			out[i] = in[data_shift+i] * window[j];
+		if(i < data_len)
+			out[i] = 0.0f;
+	}
+}
+
+void FLAC__lpc_window_data_partial_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift)
+{
+	uint32_t i, j;
+	if((part_size + data_shift) < data_len){
+		for(i = 0; i < part_size; i++)
+			out[i] = in[data_shift+i] * window[i];
+		i = flac_min(i,data_len - part_size - data_shift);
+		for(j = data_len - part_size; j < data_len; i++, j++)
+			out[i] = in[data_shift+i] * window[j];
+		if(i < data_len)
+			out[i] = 0.0f;
+	}
+}
+
+void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[])
+{
 	/* a readable, but slower, version */
 #if 0
-	FLAC__real d;
+	double d;
 	uint32_t i;
 
 	FLAC__ASSERT(lag > 0);
@@ -91,7 +128,7 @@
 	 */
 	while(lag--) {
 		for(i = lag, d = 0.0; i < data_len; i++)
-			d += data[i] * data[i - lag];
+			d += data[i] * (double)data[i - lag];
 		autoc[lag] = d;
 	}
 #endif
@@ -100,7 +137,7 @@
 	 * this version tends to run faster because of better data locality
 	 * ('data_len' is usually much larger than 'lag')
 	 */
-	FLAC__real d;
+	double d;
 	uint32_t sample, coeff;
 	const uint32_t limit = data_len - lag;
 
@@ -121,7 +158,7 @@
 	}
 }
 
-void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[])
+void FLAC__lpc_compute_lp_coefficients(const double autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[])
 {
 	uint32_t i, j;
 	double r, err, lpc[FLAC__MAX_LPC_ORDER];
@@ -547,10 +584,6 @@
 		history = data;
 		for(j = 0; j < order; j++)
 			sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
-		if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) {
-			fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization));
-			break;
-		}
 		if(FLAC__bitmath_silog2((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) {
 			fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%" PRId64 ", residual=%" PRId64 "\n", i, *data, (int64_t)(sum >> lp_quantization), ((FLAC__int64)(*data) - (sum >> lp_quantization)));
 			break;
@@ -589,7 +622,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 				else { /* order == 11 */
@@ -606,7 +639,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 			}
@@ -624,7 +657,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 				else { /* order == 9 */
@@ -639,7 +672,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 			}
@@ -657,7 +690,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 				else { /* order == 7 */
@@ -670,7 +703,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 			}
@@ -684,7 +717,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 				else { /* order == 5 */
@@ -695,7 +728,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 			}
@@ -709,7 +742,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 				else { /* order == 3 */
@@ -718,7 +751,7 @@
 						sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 			}
@@ -728,12 +761,12 @@
 						sum = 0;
 						sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
 						sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
-						residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+						residual[i] = data[i] - (sum >> lp_quantization);
 					}
 				}
 				else { /* order == 1 */
 					for(i = 0; i < (int)data_len; i++)
-						residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
+						residual[i] = data[i] - ((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
 				}
 			}
 		}
@@ -775,14 +808,154 @@
 				         sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2];
 				         sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1];
 			}
-			residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+			residual[i] = data[i] - (sum >> lp_quantization);
 		}
 	}
 }
 #endif
 
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(const FLAC__int32 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual)
+{
+	int i;
+	FLAC__int64 sum, residual_to_check;
+
+	FLAC__ASSERT(order > 0);
+	FLAC__ASSERT(order <= 32);
+
+	for(i = 0; i < (int)data_len; i++) {
+		sum = 0;
+		switch(order) {
+			case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; /* Falls through. */
+			case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; /* Falls through. */
+			case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; /* Falls through. */
+			case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; /* Falls through. */
+			case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; /* Falls through. */
+			case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; /* Falls through. */
+			case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; /* Falls through. */
+			case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; /* Falls through. */
+			case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; /* Falls through. */
+			case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; /* Falls through. */
+			case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; /* Falls through. */
+			case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; /* Falls through. */
+			case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; /* Falls through. */
+			case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; /* Falls through. */
+			case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; /* Falls through. */
+			case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; /* Falls through. */
+			case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; /* Falls through. */
+			case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; /* Falls through. */
+			case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; /* Falls through. */
+			case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; /* Falls through. */
+			case 12: sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; /* Falls through. */
+			case 11: sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; /* Falls through. */
+			case 10: sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; /* Falls through. */
+			case  9: sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; /* Falls through. */
+			case  8: sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; /* Falls through. */
+			case  7: sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; /* Falls through. */
+			case  6: sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; /* Falls through. */
+			case  5: sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; /* Falls through. */
+			case  4: sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; /* Falls through. */
+			case  3: sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; /* Falls through. */
+			case  2: sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; /* Falls through. */
+			case  1: sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1];
+		}
+		residual_to_check = data[i] - (sum >> lp_quantization);
+		 /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+		if(residual_to_check <= INT32_MIN || residual_to_check > INT32_MAX)
+			return false;
+		else
+			residual[i] = residual_to_check;
+	}
+	return true;
+}
+
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(const FLAC__int64 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual)
+{
+	int i;
+	FLAC__int64 sum, residual_to_check;
+
+	FLAC__ASSERT(order > 0);
+	FLAC__ASSERT(order <= 32);
+
+	for(i = 0; i < (int)data_len; i++) {
+		sum = 0;
+		switch(order) {
+			case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */
+			case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */
+			case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */
+			case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */
+			case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */
+			case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */
+			case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */
+			case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */
+			case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */
+			case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */
+			case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */
+			case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */
+			case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */
+			case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */
+			case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */
+			case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */
+			case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */
+			case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */
+			case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */
+			case 13: sum += qlp_coeff[12] * data[i-13]; /* Falls through. */
+			case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */
+			case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */
+			case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */
+			case  9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */
+			case  8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */
+			case  7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */
+			case  6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */
+			case  5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */
+			case  4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */
+			case  3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */
+			case  2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */
+			case  1: sum += qlp_coeff[ 0] * data[i- 1];
+		}
+		residual_to_check = data[i] - (sum >> lp_quantization);
+		/* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+		if(residual_to_check <= INT32_MIN || residual_to_check > INT32_MAX)
+			return false;
+		else
+			residual[i] = residual_to_check;
+	}
+	return true;
+}
+
 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
 
+uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order)
+{
+	/* This used to be subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order)
+	 * but that treats both the samples as well as the predictor as unknown. The
+	 * predictor is known however, so taking the log2 of the sum of the absolute values
+	 * of all coefficients is a more accurate representation of the predictor */
+	FLAC__int32 abs_sum_of_qlp_coeff = 0;
+	for(uint32_t i = 0; i < order; i++)
+		abs_sum_of_qlp_coeff += abs(qlp_coeff[i]);
+	if(abs_sum_of_qlp_coeff == 0)
+		abs_sum_of_qlp_coeff = 1;
+	return subframe_bps + FLAC__bitmath_silog2(abs_sum_of_qlp_coeff);
+}
+
+
+uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization)
+{
+	FLAC__int32 predictor_sum_bps = FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) - lp_quantization;
+	if((int)subframe_bps > predictor_sum_bps)
+		return subframe_bps + 1;
+	else
+		return predictor_sum_bps + 1;
+}
+
+#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
+/* The attribute below is to silence the undefined sanitizer of oss-fuzz.
+ * Because fuzzing feeds bogus predictors and residual samples to the
+ * decoder, having overflows in this section is unavoidable. Also,
+ * because the calculated values are audio path only, there is no
+ * potential for security problems */
+__attribute__((no_sanitize("signed-integer-overflow")))
+#endif
 void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict data)
 #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
 {
@@ -806,8 +979,10 @@
 		for(j = 0; j < order; j++) {
 			sum += qlp_coeff[j] * (*(--history));
 			sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
+#ifdef FLAC__OVERFLOW_DETECT
 			if(sumo > 2147483647ll || sumo < -2147483648ll)
 				fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo);
+#endif
 		}
 		*(data++) = *(r++) + (sum >> lp_quantization);
 	}
@@ -1064,15 +1239,13 @@
 		history = data;
 		for(j = 0; j < order; j++)
 			sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
-		if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) {
-			fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization));
-			break;
-		}
+#ifdef FLAC__OVERFLOW_DETECT
 		if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) {
 			fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization)));
 			break;
 		}
-		*(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization);
+#endif
+		*(data++) = (FLAC__int32)(*(r++) + (sum >> lp_quantization));
 	}
 }
 #else /* fully unrolled version for normal use */
@@ -1250,7 +1423,7 @@
 				}
 				else { /* order == 1 */
 					for(i = 0; i < (int)data_len; i++)
-						data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
+						data[i] = (FLAC__int32)(residual[i] + ((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization));
 				}
 			}
 		}
@@ -1294,6 +1467,87 @@
 			}
 			data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization));
 		}
+	}
+}
+#endif
+
+#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
+/* The attribute below is to silence the undefined sanitizer of oss-fuzz.
+ * Because fuzzing feeds bogus predictors and residual samples to the
+ * decoder, having overflows in this section is unavoidable. Also,
+ * because the calculated values are audio path only, there is no
+ * potential for security problems */
+__attribute__((no_sanitize("signed-integer-overflow")))
+#endif
+void FLAC__lpc_restore_signal_wide_33bit(const FLAC__int32 * flac_restrict residual, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int64 * flac_restrict data)
+#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
+{
+	uint32_t i, j;
+	FLAC__int64 sum;
+	const FLAC__int32 *r = residual;
+	const FLAC__int64 *history;
+
+	FLAC__ASSERT(order > 0);
+
+	for(i = 0; i < data_len; i++) {
+		sum = 0;
+		history = data;
+		for(j = 0; j < order; j++)
+			sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
+#ifdef FLAC__OVERFLOW_DETECT
+		if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 33) {
+			fprintf(stderr,"FLAC__lpc_restore_signal_33bit: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization)));
+			break;
+		}
+#endif
+		*(data++) = (FLAC__int64)(*(r++)) + (sum >> lp_quantization);
+	}
+}
+#else /* unrolled version for normal use */
+{
+	int i;
+	FLAC__int64 sum;
+
+	FLAC__ASSERT(order > 0);
+	FLAC__ASSERT(order <= 32);
+
+	for(i = 0; i < (int)data_len; i++) {
+		sum = 0;
+		switch(order) {
+			case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */
+			case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */
+			case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */
+			case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */
+			case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */
+			case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */
+			case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */
+			case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */
+			case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */
+			case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */
+			case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */
+			case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */
+			case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */
+			case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */
+			case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */
+			case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */
+			case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */
+			case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */
+			case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */
+			case 13: sum += qlp_coeff[12] * data[i-13]; /* Falls through. */
+			case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */
+			case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */
+			case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */
+			case  9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */
+			case  8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */
+			case  7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */
+			case  6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */
+			case  5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */
+			case  4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */
+			case  3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */
+			case  2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */
+			case  1: sum += qlp_coeff[ 0] * data[i- 1];
+		}
+		data[i] = residual[i] + (sum >> lp_quantization);
 	}
 }
 #endif
--- a/sys/src/cmd/audio/libFLAC/memory.c
+++ b/sys/src/cmd/audio/libFLAC/memory.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -94,6 +94,35 @@
 	FLAC__uint32 *pu; /* unaligned pointer */
 	union { /* union needed to comply with C99 pointer aliasing rules */
 		FLAC__uint32 *pa; /* aligned pointer */
+		void         *pv; /* aligned pointer alias */
+	} u;
+
+	FLAC__ASSERT(elements > 0);
+	FLAC__ASSERT(0 != unaligned_pointer);
+	FLAC__ASSERT(0 != aligned_pointer);
+	FLAC__ASSERT(unaligned_pointer != aligned_pointer);
+
+	if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+		return false;
+
+	pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
+	if(0 == pu) {
+		return false;
+	}
+	else {
+		if(*unaligned_pointer != 0)
+			free(*unaligned_pointer);
+		*unaligned_pointer = pu;
+		*aligned_pointer = u.pa;
+		return true;
+	}
+}
+
+FLAC__bool FLAC__memory_alloc_aligned_int64_array(size_t elements, FLAC__int64 **unaligned_pointer, FLAC__int64 **aligned_pointer)
+{
+	FLAC__int64 *pu; /* unaligned pointer */
+	union { /* union needed to comply with C99 pointer aliasing rules */
+		FLAC__int64 *pa; /* aligned pointer */
 		void         *pv; /* aligned pointer alias */
 	} u;
 
--- a/sys/src/cmd/audio/libFLAC/metadata_iterators.c
+++ b/sys/src/cmd/audio/libFLAC/metadata_iterators.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -286,27 +286,30 @@
 	do {
 		if(FLAC__metadata_simple_iterator_get_block_type(it) == FLAC__METADATA_TYPE_PICTURE) {
 			FLAC__StreamMetadata *obj = FLAC__metadata_simple_iterator_get_block(it);
-			FLAC__uint64 area = (FLAC__uint64)obj->data.picture.width * (FLAC__uint64)obj->data.picture.height;
-			/* check constraints */
-			if(
-				(type == (FLAC__StreamMetadata_Picture_Type)(-1) || type == obj->data.picture.type) &&
-				(mime_type == 0 || !strcmp(mime_type, obj->data.picture.mime_type)) &&
-				(description == 0 || !strcmp((const char *)description, (const char *)obj->data.picture.description)) &&
-				obj->data.picture.width <= max_width &&
-				obj->data.picture.height <= max_height &&
-				obj->data.picture.depth <= max_depth &&
-				obj->data.picture.colors <= max_colors &&
-				(area > max_area_seen || (area == max_area_seen && obj->data.picture.depth > max_depth_seen))
-			) {
-				if(*picture)
-					FLAC__metadata_object_delete(*picture);
-				*picture = obj;
-				max_area_seen = area;
-				max_depth_seen = obj->data.picture.depth;
+			if(0 != obj) {
+				FLAC__uint64 area = (FLAC__uint64)obj->data.picture.width * (FLAC__uint64)obj->data.picture.height;
+
+				/* check constraints */
+				if(
+					(type == (FLAC__StreamMetadata_Picture_Type)(-1) || type == obj->data.picture.type) &&
+					(mime_type == 0 || !strcmp(mime_type, obj->data.picture.mime_type)) &&
+					(description == 0 || !strcmp((const char *)description, (const char *)obj->data.picture.description)) &&
+					obj->data.picture.width <= max_width &&
+					obj->data.picture.height <= max_height &&
+					obj->data.picture.depth <= max_depth &&
+					obj->data.picture.colors <= max_colors &&
+					(area > max_area_seen || (area == max_area_seen && obj->data.picture.depth > max_depth_seen))
+				) {
+					if(*picture)
+						FLAC__metadata_object_delete(*picture);
+					*picture = obj;
+					max_area_seen = area;
+					max_depth_seen = obj->data.picture.depth;
+				}
+				else {
+					FLAC__metadata_object_delete(obj);
+				}
 			}
-			else {
-				FLAC__metadata_object_delete(obj);
-			}
 		}
 	} while(FLAC__metadata_simple_iterator_next(it));
 
@@ -443,7 +446,15 @@
 		case 0:
 			iterator->depth = 0;
 			iterator->first_offset = iterator->offset[iterator->depth] = ftello(iterator->file);
-			return read_metadata_block_header_(iterator);
+			ret = read_metadata_block_header_(iterator);
+			/* The first metadata block must be a streaminfo. If this is not the
+			 * case, the file is invalid and assumptions made elsewhere in the
+			 * code are invalid */
+			if(iterator->type != FLAC__METADATA_TYPE_STREAMINFO) {
+				iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA;
+				return false;
+			}
+			return ret;
 		case 1:
 			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
 			return false;
@@ -576,7 +587,7 @@
 	FLAC__ASSERT(0 != iterator);
 	FLAC__ASSERT(0 != iterator->file);
 
-	return iterator->offset[iterator->depth];
+	return (off_t)iterator->offset[iterator->depth];
 }
 
 FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator)
@@ -1099,6 +1110,11 @@
 		return false;
 }
 
+#if defined(_MSC_VER)
+// silence three MSVC warnings 'conversion from 'conversion from 'const __int64' to 'uint32_t', possible loss of data'
+#pragma warning ( disable : 4244 )
+#endif
+
 /* Returns the new length of the chain, or 0 if there was an error. */
 /* WATCHOUT: This can get called multiple times before a write, so
  * it should still work when this happens.
@@ -1176,6 +1192,10 @@
 	return current_length;
 }
 
+#if defined(_MSC_VER)
+#pragma warning ( default : 4244 )
+#endif
+
 static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Tell tell_cb)
 {
 	FLAC__Metadata_Node *node;
@@ -1348,6 +1368,12 @@
 
 	chain->initial_length = chain_calculate_length_(chain);
 
+	if(chain->initial_length == 0) {
+		/* Ogg FLAC file must have at least streaminfo and vorbis comment */
+		chain->status = FLAC__METADATA_CHAIN_STATUS_BAD_METADATA;
+		return false;
+	}
+
 	return true;
 }
 
@@ -1625,6 +1651,11 @@
 	LBS_BLOCK_REMOVED
 } LastBlockState;
 
+#if defined(_MSC_VER)
+// silence three MSVC warnings 'conversion from 'conversion from 'const __int64' to 'uint32_t', possible loss of data'
+#pragma warning ( disable : 4244 )
+#endif
+
 FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
 {
 	/* This does all the same checks that are in chain_prepare_for_write_()
@@ -1702,6 +1733,10 @@
 	return (current_length != chain->initial_length);
 }
 
+#if defined(_MSC_VER)
+#pragma warning ( default : 4244 )
+#endif
+
 FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats)
 {
 	struct flac_stat_s stats;
@@ -2284,18 +2319,13 @@
 	if(0 != entry->entry)
 		free(entry->entry);
 
-	if(entry->length == 0) {
-		entry->entry = 0;
-	}
-	else {
-		if(0 == (entry->entry = safe_malloc_add_2op_(entry->length, /*+*/1)))
-			return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
+	if(0 == (entry->entry = safe_malloc_add_2op_(entry->length, /*+*/1)))
+		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
 
-		if(read_cb(entry->entry, 1, entry->length, handle) != entry->length)
-			return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+	if(entry->length > 0 && read_cb(entry->entry, 1, entry->length, handle) != entry->length)
+		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
 
-		entry->entry[entry->length] = '\0';
-	}
+	entry->entry[entry->length] = '\0';
 
 	return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
 }
@@ -2326,6 +2356,11 @@
 	if(block->num_comments == 0) {
 		block->comments = 0;
 	}
+	else if(block->num_comments > (block_length >> 2)) { /* each comment needs at least 4 byte */
+		block->num_comments = 0;
+		status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA;
+		goto skip;
+	}
 	else if(0 == (block->comments = calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
 		block->num_comments = 0;
 		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
@@ -2482,6 +2517,9 @@
 		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
 	*length = unpack_uint32_(buffer, length_len);
 
+	if(*length > (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) /* data cannot be larger than FLAC metadata block */
+		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA;
+
 	if(0 != *data)
 		free(*data);
 
@@ -3422,7 +3460,7 @@
 
 void set_file_stats_(const char *filename, struct flac_stat_s *stats)
 {
-#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L)
+#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) && !defined(_WIN32)
 	struct timespec srctime[2] = {};
 	srctime[0].tv_sec = stats->st_atime;
 	srctime[1].tv_sec = stats->st_mtime;
--- a/sys/src/cmd/audio/libFLAC/metadata_object.c
+++ b/sys/src/cmd/audio/libFLAC/metadata_object.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -98,7 +98,7 @@
 /* realloc() failure leaves entry unchanged */
 static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, uint32_t length)
 {
-	FLAC__byte *x = safe_realloc_add_2op_(*entry, length, /*+*/1);
+	FLAC__byte *x = safe_realloc_nofree_add_2op_(*entry, length, /*+*/1);
 	if (x != NULL) {
 		x[length] = '\0';
 		*entry = x;
@@ -130,7 +130,9 @@
 	to->length = from->length;
 	if (from->entry == 0) {
 		FLAC__ASSERT(from->length == 0);
-		to->entry = 0;
+		if ((to->entry = safe_malloc_(1)) == NULL)
+			return false;
+		to->entry[0] = '\0';
 	}
 	else {
 		FLAC__byte *x;
@@ -950,8 +952,13 @@
 			free(object->data.seek_table.points);
 			object->data.seek_table.points = 0;
 		}
-		else if ((object->data.seek_table.points = safe_realloc_(object->data.seek_table.points, new_size)) == NULL)
-			return false;
+		else {
+			/* Leave object->data.seek_table.points untouched if realloc fails */
+			FLAC__StreamMetadata_SeekPoint *tmpptr;
+			if ((tmpptr = realloc(object->data.seek_table.points, new_size)) == NULL)
+				return false;
+			object->data.seek_table.points = tmpptr;
+		}
 
 		/* if growing, set new elements to placeholders */
 		if (new_size > old_size) {
@@ -1124,7 +1131,7 @@
 		if (num > 32768) {
 			/* Set the bound and recalculate samples accordingly. */
 			num = 32768;
-			samples = total_samples / num;
+			samples = (uint32_t)(total_samples / num);
 		}
 
 		i = seek_table->num_points;
@@ -1171,8 +1178,18 @@
 		FLAC__ASSERT(object->data.vorbis_comment.num_comments == 0);
 		if (new_num_comments == 0)
 			return true;
-		else if ((object->data.vorbis_comment.comments = vorbiscomment_entry_array_new_(new_num_comments)) == NULL)
-			return false;
+		else {
+			if ((object->data.vorbis_comment.comments = vorbiscomment_entry_array_new_(new_num_comments)) == NULL)
+				return false;
+			for (uint32_t i = 0; i < new_num_comments; i++) {
+				object->data.vorbis_comment.comments[i].length = 0;
+				if ((object->data.vorbis_comment.comments[i].entry = safe_malloc_(1)) == NULL) {
+					object->data.vorbis_comment.num_comments = i+1;
+					return false;
+				}
+				object->data.vorbis_comment.comments[i].entry[0] = '\0';
+			}
+		}
 	}
 	else {
 		const size_t old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
@@ -1197,17 +1214,24 @@
 			object->data.vorbis_comment.comments = 0;
 		}
 		else {
-			FLAC__StreamMetadata_VorbisComment_Entry *oldptr = object->data.vorbis_comment.comments;
-			if ((object->data.vorbis_comment.comments = realloc(object->data.vorbis_comment.comments, new_size)) == NULL) {
-				vorbiscomment_entry_array_delete_(oldptr, object->data.vorbis_comment.num_comments);
-				object->data.vorbis_comment.num_comments = 0;
+			/* Leave object->data.vorbis_comment.comments untouched if realloc fails */
+			FLAC__StreamMetadata_VorbisComment_Entry *tmpptr;
+			if ((tmpptr = realloc(object->data.vorbis_comment.comments, new_size)) == NULL)
 				return false;
-			}
+			object->data.vorbis_comment.comments = tmpptr;
 		}
 
 		/* if growing, zero all the length/pointers of new elements */
-		if (new_size > old_size)
-			memset(object->data.vorbis_comment.comments + object->data.vorbis_comment.num_comments, 0, new_size - old_size);
+		if (new_size > old_size) {
+			for (uint32_t i = object->data.vorbis_comment.num_comments; i < new_num_comments; i++) {
+				object->data.vorbis_comment.comments[i].length = 0;
+				if ((object->data.vorbis_comment.comments[i].entry = safe_malloc_(1)) == NULL) {
+					object->data.vorbis_comment.num_comments = i+1;
+					return false;
+				}
+				object->data.vorbis_comment.comments[i].entry[0] = '\0';
+			}
+		}
 	}
 
 	object->data.vorbis_comment.num_comments = new_num_comments;
@@ -1229,6 +1253,7 @@
 FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, uint32_t comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy)
 {
 	FLAC__StreamMetadata_VorbisComment *vc;
+	FLAC__StreamMetadata_VorbisComment_Entry temp;
 
 	FLAC__ASSERT(object != NULL);
 	FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
@@ -1243,9 +1268,10 @@
 		return false;
 
 	/* move all comments >= comment_num forward one space */
+	/* reuse newly added empty comment */
+	temp = vc->comments[vc->num_comments-1];
 	memmove(&vc->comments[comment_num+1], &vc->comments[comment_num], sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(vc->num_comments-1-comment_num));
-	vc->comments[comment_num].length = 0;
-	vc->comments[comment_num].entry = 0;
+	vc->comments[comment_num] = temp;
 
 	return FLAC__metadata_object_vorbiscomment_set_comment(object, comment_num, entry, copy);
 }
@@ -1502,8 +1528,13 @@
 			free(track->indices);
 			track->indices = 0;
 		}
-		else if ((track->indices = safe_realloc_(track->indices, new_size)) == NULL)
-			return false;
+		else {
+			/* Leave track->indices untouched if realloc fails */
+			FLAC__StreamMetadata_CueSheet_Index *tmpptr;
+			if ((tmpptr = realloc(track->indices, new_size)) == NULL)
+				return false;
+			track->indices = tmpptr;
+		}
 
 		/* if growing, zero all the lengths/pointers of new elements */
 		if (new_size > old_size)
@@ -1597,8 +1628,13 @@
 			free(object->data.cue_sheet.tracks);
 			object->data.cue_sheet.tracks = 0;
 		}
-		else if ((object->data.cue_sheet.tracks = safe_realloc_(object->data.cue_sheet.tracks, new_size)) == NULL)
-			return false;
+		else {
+			/* Leave object->data.cue_sheet.tracks untouched if realloc fails */
+			FLAC__StreamMetadata_CueSheet_Track *tmpptr;
+			if ((tmpptr = realloc(object->data.cue_sheet.tracks, new_size)) == NULL)
+				return false;
+			object->data.cue_sheet.tracks = tmpptr;
+		}
 
 		/* if growing, zero all the lengths/pointers of new elements */
 		if (new_size > old_size)
--- a/sys/src/cmd/audio/libFLAC/mkfile
+++ b/sys/src/cmd/audio/libFLAC/mkfile
@@ -26,6 +26,6 @@
 	window.$O\
 
 CC=pcc
-CFLAGS=-I. -I../libogg -DPACKAGE_VERSION="1.3.4" -DPlan9 -DFLAC__NO_ASM -DFLAC__HAS_OGG -DFLAC__ALIGN_MALLOC_DATA -D_C99_SNPRINTF_EXTENSION -D_BSD_EXTENSION -D_POSIX_SOURCE -DHAVE_STDINT_H -DNDEBUG -c
+CFLAGS=-I. -I../libogg -DPACKAGE_VERSION="1.4.0" -DPlan9 -DFLAC__NO_ASM -DFLAC__HAS_OGG -DFLAC__ALIGN_MALLOC_DATA -D_C99_SNPRINTF_EXTENSION -D_BSD_EXTENSION -Dcosf=cos -Dfabsf=fabs -D_POSIX_SOURCE -DHAVE_STDINT_H -DNDEBUG -c
 
 </sys/src/cmd/mklib
--- a/sys/src/cmd/audio/libFLAC/ogg_decoder_aspect.c
+++ b/sys/src/cmd/audio/libFLAC/ogg_decoder_aspect.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2002-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/ogg_encoder_aspect.c
+++ b/sys/src/cmd/audio/libFLAC/ogg_encoder_aspect.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2002-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/ogg_helper.c
+++ b/sys/src/cmd/audio/libFLAC/ogg_helper.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2004-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/ogg_mapping.c
+++ b/sys/src/cmd/audio/libFLAC/ogg_mapping.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2004-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/all.h
+++ b/sys/src/cmd/audio/libFLAC/private/all.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/bitmath.h
+++ b/sys/src/cmd/audio/libFLAC/private/bitmath.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/bitreader.h
+++ b/sys/src/cmd/audio/libFLAC/private/bitreader.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,6 +53,8 @@
 FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd);
 void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */
 FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br);
+void FLAC__bitreader_set_framesync_location(FLAC__BitReader *br);
+FLAC__bool FLAC__bitreader_rewind_to_after_last_seen_framesync(FLAC__BitReader *br);
 void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out);
 
 /*
@@ -67,6 +69,10 @@
 FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br);
 uint32_t FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br);
 uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br);
+void FLAC__bitreader_set_limit(FLAC__BitReader *br, uint32_t limit);
+void FLAC__bitreader_remove_limit(FLAC__BitReader *br);
+uint32_t FLAC__bitreader_limit_remaining(FLAC__BitReader *br);
+void FLAC__bitreader_limit_invalidate(FLAC__BitReader *br);
 
 /*
  * read functions
@@ -75,6 +81,7 @@
 FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits);
 FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, uint32_t bits);
 FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, uint32_t bits);
+FLAC__bool FLAC__bitreader_read_raw_int64(FLAC__BitReader *br, FLAC__int64 *val, uint32_t bits);
 FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/
 FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, uint32_t bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */
 FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, uint32_t nvals); /* WATCHOUT: does not CRC the read data! */
--- a/sys/src/cmd/audio/libFLAC/private/bitwriter.h
+++ b/sys/src/cmd/audio/libFLAC/private/bitwriter.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -83,6 +83,7 @@
 FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits);
 FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits);
 FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits);
+FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits);
 FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/
 FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals);
 FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, uint32_t val);
--- a/sys/src/cmd/audio/libFLAC/private/cpu.h
+++ b/sys/src/cmd/audio/libFLAC/private/cpu.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -63,6 +63,7 @@
 /* SSE intrinsics support by ICC/MSVC/GCC */
 #if defined __INTEL_COMPILER
   #define FLAC__SSE_TARGET(x)
+  #define FLAC__FAST_MATH_TARGET(x)
   #define FLAC__SSE_SUPPORTED 1
   #define FLAC__SSE2_SUPPORTED 1
   #if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */
@@ -69,15 +70,18 @@
     #define FLAC__SSSE3_SUPPORTED 1
     #define FLAC__SSE4_1_SUPPORTED 1
   #endif
-  #if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */
-    #define FLAC__AVX_SUPPORTED 1
+  #ifdef FLAC__USE_AVX
+    #if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */
+      #define FLAC__AVX_SUPPORTED 1
+    #endif
+    #if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */
+      #define FLAC__AVX2_SUPPORTED 1
+      #define FLAC__FMA_SUPPORTED 1
+    #endif
   #endif
-  #if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */
-    #define FLAC__AVX2_SUPPORTED 1
-    #define FLAC__FMA_SUPPORTED 1
-  #endif
 #elif defined __clang__ && __has_attribute(__target__) /* clang */
   #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x)))
+  #define FLAC__FAST_MATH_TARGET(x) __attribute__ ((__target__ (x), optimize("-ffast-math")))
   #if __has_builtin(__builtin_ia32_maxps)
     #define FLAC__SSE_SUPPORTED 1
   #endif
@@ -90,17 +94,20 @@
   #if __has_builtin(__builtin_ia32_pmuldq128)
     #define FLAC__SSE4_1_SUPPORTED 1
   #endif
-  #if __has_builtin(__builtin_ia32_maxps256)
-    #define FLAC__AVX_SUPPORTED 1
+  #ifdef FLAC__USE_AVX
+    #if __has_builtin(__builtin_ia32_maxps256)
+      #define FLAC__AVX_SUPPORTED 1
+    #endif
+    #if __has_builtin(__builtin_ia32_pabsd256)
+      #define FLAC__AVX2_SUPPORTED 1
+    #endif
+    #if __has_builtin(__builtin_ia32_vfmaddps)
+      #define FLAC__FMA_SUPPORTED 1
+    #endif
   #endif
-  #if __has_builtin(__builtin_ia32_pabsd256)
-    #define FLAC__AVX2_SUPPORTED 1
-  #endif
-  #if __has_builtin(__builtin_ia32_vfmaddps)
-    #define FLAC__FMA_SUPPORTED 1
-  #endif
 #elif defined __GNUC__ && !defined __clang__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* GCC 4.9+ */
   #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x)))
+  #define FLAC__FAST_MATH_TARGET(x) __attribute__ ((__target__ (x), optimize("-ffast-math")))
   #define FLAC__SSE_SUPPORTED 1
   #define FLAC__SSE2_SUPPORTED 1
   #define FLAC__SSSE3_SUPPORTED 1
@@ -112,6 +119,7 @@
   #endif
 #elif defined _MSC_VER
   #define FLAC__SSE_TARGET(x)
+  #define FLAC__FAST_MATH_TARGET(x)
   #define FLAC__SSE_SUPPORTED 1
   #define FLAC__SSE2_SUPPORTED 1
   #if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */
@@ -118,15 +126,18 @@
     #define FLAC__SSSE3_SUPPORTED 1
     #define FLAC__SSE4_1_SUPPORTED 1
   #endif
-  #if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */
-    #define FLAC__AVX_SUPPORTED 1
+  #ifdef FLAC__USE_AVX
+    #if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */
+      #define FLAC__AVX_SUPPORTED 1
+    #endif
+    #if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */
+      #define FLAC__AVX2_SUPPORTED 1
+      #define FLAC__FMA_SUPPORTED 1
+    #endif
   #endif
-  #if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */
-    #define FLAC__AVX2_SUPPORTED 1
-    #define FLAC__FMA_SUPPORTED 1
-  #endif
 #else
   #define FLAC__SSE_TARGET(x)
+  #define FLAC__FAST_MATH_TARGET(x)
   #ifdef __SSE__
     #define FLAC__SSE_SUPPORTED 1
   #endif
@@ -139,14 +150,16 @@
   #ifdef __SSE4_1__
     #define FLAC__SSE4_1_SUPPORTED 1
   #endif
-  #ifdef __AVX__
-    #define FLAC__AVX_SUPPORTED 1
-  #endif
-  #ifdef __AVX2__
-    #define FLAC__AVX2_SUPPORTED 1
-  #endif
-  #ifdef __FMA__
-    #define FLAC__FMA_SUPPORTED 1
+  #ifdef FLAC__USE_AVX
+    #ifdef __AVX__
+      #define FLAC__AVX_SUPPORTED 1
+    #endif
+    #ifdef __AVX2__
+      #define FLAC__AVX2_SUPPORTED 1
+    #endif
+    #ifdef __FMA__
+      #define FLAC__FMA_SUPPORTED 1
+    #endif
   #endif
 #endif /* compiler version */
 #endif /* intrinsics support */
--- a/sys/src/cmd/audio/libFLAC/private/crc.h
+++ b/sys/src/cmd/audio/libFLAC/private/crc.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2018  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/fixed.h
+++ b/sys/src/cmd/audio/libFLAC/private/fixed.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,6 +56,8 @@
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
 uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
 # ifndef FLAC__NO_ASM
 #  if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
 #   ifdef FLAC__SSE2_SUPPORTED
@@ -74,6 +76,8 @@
 #else
 uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
 uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
 #endif
 
 /*
@@ -88,6 +92,8 @@
  *	OUT residual[0,data_len-1]        residual signal
  */
 void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]);
+void FLAC__fixed_compute_residual_wide(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]);
+void FLAC__fixed_compute_residual_wide_33bit(const FLAC__int64 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]);
 
 /*
  *	FLAC__fixed_restore_signal()
@@ -103,5 +109,7 @@
  *	OUT data[0,data_len-1]            original signal
  */
 void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]);
+void FLAC__fixed_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]);
+void FLAC__fixed_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int64 data[]);
 
 #endif
--- a/sys/src/cmd/audio/libFLAC/private/float.h
+++ b/sys/src/cmd/audio/libFLAC/private/float.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2004-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/format.h
+++ b/sys/src/cmd/audio/libFLAC/private/format.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/lpc.h
+++ b/sys/src/cmd/audio/libFLAC/private/lpc.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,6 +55,9 @@
  *	IN data_len
  */
 void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len);
+void FLAC__lpc_window_data_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len);
+void FLAC__lpc_window_data_partial(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift);
+void FLAC__lpc_window_data_partial_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift);
 
 /*
  *	FLAC__lpc_compute_autocorrelation()
@@ -68,44 +71,40 @@
  *	IN 0 < lag <= data_len
  *	OUT autoc[0,lag-1]
  */
-void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
+void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
 #ifndef FLAC__NO_ASM
-#  ifdef FLAC__CPU_IA32
-#    ifdef FLAC__HAS_NASM
-void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
+#  if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
+#    ifdef FLAC__SSE2_SUPPORTED
+void FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
 #    endif
 #  endif
-#  if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
-#    ifdef FLAC__SSE_SUPPORTED
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
+#  if defined FLAC__CPU_X86_64 && FLAC__HAS_X86INTRIN
+#    ifdef FLAC__FMA_SUPPORTED
+void FLAC__lpc_compute_autocorrelation_intrin_fma_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_fma_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_fma_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
 #    endif
 #  endif
 #if defined(FLAC__CPU_PPC64) && defined(FLAC__USE_VSX)
 #ifdef FLAC__HAS_TARGET_POWER9
-void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_10(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_14(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
 #endif
 #ifdef FLAC__HAS_TARGET_POWER8
-void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
-void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_10(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_14(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
 #endif
 #endif
+#if defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN && FLAC__HAS_A64NEONINTRIN
+void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_10(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
+void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
 #endif
+#endif /* FLAC__NO_ASM */
 
 /*
  *	FLAC__lpc_compute_lp_coefficients()
@@ -128,7 +127,7 @@
  *	         in lp_coeff[8][0,8], the LP coefficients for order 8 will be
  *			 in lp_coeff[7][0,7], etc.
  */
-void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]);
+void FLAC__lpc_compute_lp_coefficients(const double autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]);
 
 /*
  *	FLAC__lpc_quantize_coefficients()
@@ -167,7 +166,14 @@
  */
 void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
 void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(const FLAC__int64 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
 #ifndef FLAC__NO_ASM
+#   ifdef FLAC__CPU_ARM64
+void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
+void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_neon(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
+#   endif
+
 #  ifdef FLAC__CPU_IA32
 #    ifdef FLAC__HAS_NASM
 void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
@@ -194,6 +200,9 @@
 
 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
 
+uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order);
+uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization);
+
 /*
  *	FLAC__lpc_restore_signal()
  *	--------------------------------------------------------------------
@@ -211,22 +220,7 @@
  */
 void FLAC__lpc_restore_signal(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
 void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-#ifndef FLAC__NO_ASM
-#  ifdef FLAC__CPU_IA32
-#    ifdef FLAC__HAS_NASM
-void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-#    endif /* FLAC__HAS_NASM */
-#  endif /* FLAC__CPU_IA32 */
-#  if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
-#    ifdef FLAC__SSE4_1_SUPPORTED
-void FLAC__lpc_restore_signal_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-void FLAC__lpc_restore_signal_16_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-#    endif
-#  endif
-#endif /* FLAC__NO_ASM */
+void FLAC__lpc_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int64 data[]);
 
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 
--- a/sys/src/cmd/audio/libFLAC/private/macros.h
+++ b/sys/src/cmd/audio/libFLAC/private/macros.h
@@ -1,5 +1,5 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2012-2016  Xiph.org Foundation
+ * Copyright (C) 2012-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/memory.h
+++ b/sys/src/cmd/audio/libFLAC/private/memory.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,6 +48,7 @@
 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address);
 FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer);
 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer);
+FLAC__bool FLAC__memory_alloc_aligned_int64_array(size_t elements, FLAC__int64 **unaligned_pointer, FLAC__int64 **aligned_pointer);
 FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer);
 FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer);
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
--- a/sys/src/cmd/audio/libFLAC/private/metadata.h
+++ b/sys/src/cmd/audio/libFLAC/private/metadata.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2002-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/ogg_decoder_aspect.h
+++ b/sys/src/cmd/audio/libFLAC/private/ogg_decoder_aspect.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2002-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/ogg_encoder_aspect.h
+++ b/sys/src/cmd/audio/libFLAC/private/ogg_encoder_aspect.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2002-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/ogg_helper.h
+++ b/sys/src/cmd/audio/libFLAC/private/ogg_helper.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2004-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/ogg_mapping.h
+++ b/sys/src/cmd/audio/libFLAC/private/ogg_mapping.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec
  * Copyright (C) 2004-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/stream_encoder.h
+++ b/sys/src/cmd/audio/libFLAC/private/stream_encoder.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/stream_encoder_framing.h
+++ b/sys/src/cmd/audio/libFLAC/private/stream_encoder_framing.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/private/window.h
+++ b/sys/src/cmd/audio/libFLAC/private/window.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2006-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/protected/all.h
+++ b/sys/src/cmd/audio/libFLAC/protected/all.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/protected/stream_decoder.h
+++ b/sys/src/cmd/audio/libFLAC/protected/stream_decoder.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,13 +53,8 @@
 } FLAC__StreamDecoderProtected;
 
 /*
- * return the number of input bytes consumed
+ * Return the number of input bytes consumed
  */
 uint32_t FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder);
-
-/*
- * return client_data from decoder
- */
-FLAC_API void *get_client_data_from_decoder(FLAC__StreamDecoder *decoder);
 
 #endif
--- a/sys/src/cmd/audio/libFLAC/protected/stream_encoder.h
+++ b/sys/src/cmd/audio/libFLAC/protected/stream_encoder.h
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -61,6 +61,7 @@
 	FLAC__APODIZATION_TUKEY,
 	FLAC__APODIZATION_PARTIAL_TUKEY,
 	FLAC__APODIZATION_PUNCHOUT_TUKEY,
+	FLAC__APODIZATION_SUBDIVIDE_TUKEY,
 	FLAC__APODIZATION_WELCH
 } FLAC__ApodizationFunction;
 
@@ -78,6 +79,10 @@
 			FLAC__real start;
 			FLAC__real end;
 		} multiple_tukey;
+		struct {
+			FLAC__real p;
+			FLAC__int32 parts;
+		} subdivide_tukey;
 	} parameters;
 } FLAC__ApodizationSpecification;
 
@@ -107,6 +112,7 @@
 	uint32_t max_residual_partition_order;
 	uint32_t rice_parameter_search_dist;
 	FLAC__uint64 total_samples_estimate;
+	FLAC__bool limit_min_bitrate;
 	FLAC__StreamMetadata **metadata;
 	uint32_t num_metadata_blocks;
 	FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset;
--- a/sys/src/cmd/audio/libFLAC/share/alloc.h
+++ b/sys/src/cmd/audio/libFLAC/share/alloc.h
@@ -1,6 +1,6 @@
 /* alloc - Convenience routines for safely allocating memory
  * Copyright (C) 2007-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,7 +42,7 @@
  */
 
 #include <limits.h> /* for SIZE_MAX */
-#if HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
 #include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
 #endif
 #include <stdlib.h> /* for size_t, malloc(), etc */
@@ -63,11 +63,31 @@
 # define SIZE_MAX SIZE_T_MAX
 #endif
 
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+extern int alloc_check_threshold, alloc_check_counter;
+
+static inline int alloc_check() {
+	if(alloc_check_threshold == INT32_MAX)
+		return 0;
+	else if(alloc_check_counter++ == alloc_check_threshold)
+		return 1;
+	else
+		return 0;
+}
+
+#endif
+
 /* avoid malloc()ing 0 bytes, see:
  * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
 */
+
 static inline void *safe_malloc_(size_t size)
 {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+	/* Fail if requested */
+	if(alloc_check())
+		return NULL;
+#endif
 	/* malloc(0) is undefined; FLAC src convention is to always allocate */
 	if(!size)
 		size++;
@@ -74,8 +94,27 @@
 	return malloc(size);
 }
 
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+static inline void *malloc_(size_t size)
+{
+	/* Fail if requested */
+	if(alloc_check())
+		return NULL;
+	return malloc(size);
+}
+#else
+#define malloc_ malloc
+#endif
+
+
+
 static inline void *safe_calloc_(size_t nmemb, size_t size)
 {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+	/* Fail if requested */
+	if(alloc_check())
+		return NULL;
+#endif
 	if(!nmemb || !size)
 		return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
 	return calloc(nmemb, size);
@@ -127,7 +166,7 @@
 	size1 *= size2;
 	if(size1 > SIZE_MAX / size3)
 		return 0;
-	return malloc(size1*size3);
+	return malloc_(size1*size3);
 }
 
 /* size1*size2 + size3 */
@@ -150,11 +189,18 @@
 		return 0;
 	if(size1 > SIZE_MAX / size2)
 		return 0;
-	return malloc(size1*size2);
+	return malloc_(size1*size2);
 }
 
 static inline void *safe_realloc_(void *ptr, size_t size)
 {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+	/* Fail if requested */
+	if(alloc_check() && size > 0) {
+		free(ptr);
+		return NULL;
+	}
+#endif
 	void *oldptr = ptr;
 	void *newptr = realloc(ptr, size);
 	if(size > 0 && newptr == 0)
@@ -161,17 +207,44 @@
 		free(oldptr);
 	return newptr;
 }
-static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
+
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+static inline void *realloc_(void *ptr, size_t size)
 {
+	/* Fail if requested */
+	if(alloc_check())
+		return NULL;
+	return realloc(ptr, size);
+}
+#else
+#define realloc_ realloc
+#endif
+
+
+static inline void *safe_realloc_nofree_add_2op_(void *ptr, size_t size1, size_t size2)
+{
 	size2 += size1;
+	if(size2 < size1)
+		return 0;
+	return realloc_(ptr, size2);
+}
+
+static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
+{
+	size2 += size1;
 	if(size2 < size1) {
 		free(ptr);
 		return 0;
 	}
-	return realloc(ptr, size2);
+	size3 += size2;
+	if(size3 < size2) {
+		free(ptr);
+		return 0;
+	}
+	return safe_realloc_(ptr, size3);
 }
 
-static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
+static inline void *safe_realloc_nofree_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
 {
 	size2 += size1;
 	if(size2 < size1)
@@ -179,10 +252,10 @@
 	size3 += size2;
 	if(size3 < size2)
 		return 0;
-	return realloc(ptr, size3);
+	return realloc_(ptr, size3);
 }
 
-static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
+static inline void *safe_realloc_nofree_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
 {
 	size2 += size1;
 	if(size2 < size1)
@@ -193,7 +266,7 @@
 	size4 += size3;
 	if(size4 < size3)
 		return 0;
-	return realloc(ptr, size4);
+	return realloc_(ptr, size4);
 }
 
 static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
@@ -200,11 +273,22 @@
 {
 	if(!size1 || !size2)
 		return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
-	if(size1 > SIZE_MAX / size2)
+	if(size1 > SIZE_MAX / size2) {
+		free(ptr);
 		return 0;
+	}
 	return safe_realloc_(ptr, size1*size2);
 }
 
+static inline void *safe_realloc_nofree_mul_2op_(void *ptr, size_t size1, size_t size2)
+{
+	if(!size1 || !size2)
+		return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
+	if(size1 > SIZE_MAX / size2)
+		return 0;
+	return realloc_(ptr, size1*size2);
+}
+
 /* size1 * (size2 + size3) */
 static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
 {
@@ -211,9 +295,22 @@
 	if(!size1 || (!size2 && !size3))
 		return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
 	size2 += size3;
-	if(size2 < size3)
+	if(size2 < size3) {
+		free(ptr);
 		return 0;
+	}
 	return safe_realloc_mul_2op_(ptr, size1, size2);
+}
+
+/* size1 * (size2 + size3) */
+static inline void *safe_realloc_nofree_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
+{
+	if(!size1 || (!size2 && !size3))
+		return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
+	size2 += size3;
+	if(size2 < size3)
+		return 0;
+	return safe_realloc_nofree_mul_2op_(ptr, size1, size2);
 }
 
 #endif
--- a/sys/src/cmd/audio/libFLAC/share/compat.h
+++ b/sys/src/cmd/audio/libFLAC/share/compat.h
@@ -1,5 +1,5 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2012-2016  Xiph.org Foundation
+ * Copyright (C) 2012-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,6 +39,9 @@
 #ifndef FLAC__SHARE__COMPAT_H
 #define FLAC__SHARE__COMPAT_H
 
+#include <stddef.h>
+#include <stdarg.h>
+
 #if defined _WIN32 && !defined __CYGWIN__
 /* where MSVC puts unlink() */
 # include <io.h>
@@ -62,7 +65,7 @@
 #define FLAC__off_t off_t
 #endif
 
-#if HAVE_INTTYPES_H
+#ifdef HAVE_INTTYPES_H
 #define __STDC_FORMAT_MACROS
 #include <inttypes.h>
 #endif
@@ -138,6 +141,29 @@
 #    define PRId64 "I64d"
 #    define PRIx64 "I64x"
 #  endif
+#  if defined(_USING_V110_SDK71_) && !defined(_DLL)
+#    pragma message("WARNING: This compile will NOT FUNCTION PROPERLY on Windows XP. See comments in include/share/compat.h for details")
+#define FLAC__USE_FILELENGTHI64
+/*
+ *************************************************************************************
+ * V110_SDK71, in MSVC 2017 also known as v141_xp, is a platform toolset that is supposed
+ * to target Windows XP. It turns out however that certain functions provided silently fail
+ * on Windows XP only, which makes debugging challenging. This only occurs when building with
+ * /MT. This problem has been reported to Microsoft, but there hasn't been a fix for years. See
+ * https://web.archive.org/web/20170327195018/https://connect.microsoft.com/VisualStudio/feedback/details/1557168/wstat64-returns-1-on-xp-always
+ *
+ * It is known that this problem affects the functions _wstat64 (used by flac_stat i.e.
+ * stat64_utf8) and _fstat64 (i.e. flac_fstat) and therefore affects both libFLAC in
+ * several places as well as the flac and metaflac command line tools
+ *
+ * As the extent of this problem is unknown and Microsoft seems unwilling to fix it,
+ * users of libFLAC building with Visual Studio are encouraged to not use the /MT compile
+ * switch when explicitly targeting Windows XP. When use of /MT is deemed necessary with
+ * this toolset, be sure to check whether your application works properly on Windows XP.
+ * It is also possible to build for Windows XP with MinGW instead.
+ *************************************************************************************
+*/
+#  endif
 #endif /* defined _MSC_VER */
 
 #ifdef _WIN32
@@ -147,15 +173,13 @@
 #define flac_printf printf_utf8
 #define flac_fprintf fprintf_utf8
 #define flac_vfprintf vfprintf_utf8
+#define flac_fopen fopen_utf8
+#define flac_chmod chmod_utf8
+#define flac_utime utime_utf8
+#define flac_unlink unlink_utf8
+#define flac_rename rename_utf8
+#define flac_stat stat64_utf8
 
-#include "share/windows_unicode_filenames.h"
-#define flac_fopen flac_internal_fopen_utf8
-#define flac_chmod flac_internal_chmod_utf8
-#define flac_utime flac_internal_utime_utf8
-#define flac_unlink flac_internal_unlink_utf8
-#define flac_rename flac_internal_rename_utf8
-#define flac_stat flac_internal_stat64_utf8
-
 #else
 
 #define flac_printf printf
@@ -200,7 +224,6 @@
  *
  * This function wraps the MS version to behave more like the ISO version.
  */
-#include <stdarg.h>
 #ifdef __cplusplus
 extern "C" {
 #endif
--- a/sys/src/cmd/audio/libFLAC/share/endswap.h
+++ b/sys/src/cmd/audio/libFLAC/share/endswap.h
@@ -1,5 +1,5 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2012-2016  Xiph.org Foundation
+ * Copyright (C) 2012-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,10 +31,10 @@
 
 /* It is assumed that this header will be included after "config.h". */
 
-#if HAVE_BSWAP32			/* GCC and Clang */
+#ifdef HAVE_BSWAP32			/* GCC and Clang */
 
 /* GCC prior to 4.8 didn't provide bswap16 on x86_64 */
-#if ! HAVE_BSWAP16
+#ifndef HAVE_BSWAP16
 static inline unsigned short __builtin_bswap16(unsigned short a)
 {
 	return (a<<8)|(a>>8);
--- a/sys/src/cmd/audio/libFLAC/share/macros.h
+++ b/sys/src/cmd/audio/libFLAC/share/macros.h
@@ -1,5 +1,5 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2013-2016  Xiph.org Foundation
+ * Copyright (C) 2013-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/share/private.h
+++ b/sys/src/cmd/audio/libFLAC/share/private.h
@@ -1,5 +1,5 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2013-2016  Xiph.org Foundation
+ * Copyright (C) 2013-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,6 +36,7 @@
  * Unpublished debug routines from libFLAC. This should not be used from any
  * client code other than code shipped with the FLAC sources.
  */
+FLAC_API FLAC__bool FLAC__stream_encoder_disable_instruction_set(FLAC__StreamEncoder *encoder, FLAC__bool value);
 FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
 FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
 FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
--- a/sys/src/cmd/audio/libFLAC/share/safe_str.h
+++ b/sys/src/cmd/audio/libFLAC/share/safe_str.h
@@ -1,5 +1,5 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2013-2016  Xiph.org Foundation
+ * Copyright (C) 2013-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
--- a/sys/src/cmd/audio/libFLAC/stream_decoder.c
+++ b/sys/src/cmd/audio/libFLAC/stream_decoder.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,6 @@
 #include "protected/stream_decoder.h"
 #include "private/bitreader.h"
 #include "private/bitmath.h"
-#include "private/cpu.h"
 #include "private/crc.h"
 #include "private/fixed.h"
 #include "private/format.h"
@@ -75,7 +74,7 @@
 
 static void set_defaults_(FLAC__StreamDecoder *decoder);
 static FILE *get_binary_stdin_(void);
-static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels);
+static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps);
 static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id);
 static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder);
 static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder);
@@ -95,6 +94,7 @@
 static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode);
 static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_t predictor_order, uint32_t partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended);
 static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);
+static void       undo_channel_coding(FLAC__StreamDecoder *decoder);
 static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data);
 #if FLAC__HAS_OGG
 static FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes);
@@ -128,17 +128,13 @@
 	FLAC__StreamDecoderWriteCallback write_callback;
 	FLAC__StreamDecoderMetadataCallback metadata_callback;
 	FLAC__StreamDecoderErrorCallback error_callback;
-	/* generic 32-bit datapath: */
-	void (*local_lpc_restore_signal)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-	/* generic 64-bit datapath: */
-	void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
-	/* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */
-	void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]);
 	void *client_data;
 	FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
 	FLAC__BitReader *input;
 	FLAC__int32 *output[FLAC__MAX_CHANNELS];
 	FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
+	FLAC__int64 *side_subframe;
+	FLAC__bool side_subframe_in_use;
 	FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
 	uint32_t output_capacity, output_channels;
 	FLAC__uint32 fixed_block_size, next_fixed_block_size;
@@ -151,7 +147,6 @@
 	size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
 	FLAC__Frame frame;
 	FLAC__bool cached; /* true if there is a byte in lookahead */
-	FLAC__CPUInfo cpuinfo;
 	FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */
 	FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
 	/* unaligned (original) pointers to allocated data */
@@ -162,8 +157,10 @@
 	FLAC__MD5Context md5context;
 	FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
 	/* (the rest of these are only used for seeking) */
-	FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
+	FLAC__Frame last_frame; /* holds the info of the last frame we decoded or seeked to */
+	FLAC__bool last_frame_is_set;
 	FLAC__uint64 first_frame_offset; /* hint to the seek routine of where in the stream the first audio frame starts */
+	FLAC__uint64 last_seen_framesync; /* if tell callback works, the location of the last seen frame sync code, to rewind to if needed */
 	FLAC__uint64 target_sample;
 	uint32_t unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */
 	FLAC__bool got_a_frame; /* hack needed in Ogg FLAC seek routine to check when process_single() actually writes a frame */
@@ -230,7 +227,8 @@
 	"FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC",
 	"FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER",
 	"FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH",
-	"FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM"
+	"FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM",
+	"FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA"
 };
 
 /***********************************************************************
@@ -285,6 +283,8 @@
 		decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
 	}
 
+	decoder->private_->side_subframe = 0;
+
 	decoder->private_->output_capacity = 0;
 	decoder->private_->output_channels = 0;
 	decoder->private_->has_seek_table = false;
@@ -369,48 +369,6 @@
 		return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
 #endif
 
-	/*
-	 * get the CPU info and set the function pointers
-	 */
-	FLAC__cpu_info(&decoder->private_->cpuinfo);
-	/* first default to the non-asm routines */
-	decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
-	decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide;
-	decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
-	/* now override with asm where appropriate */
-#ifndef FLAC__NO_ASM
-	if(decoder->private_->cpuinfo.use_asm) {
-#ifdef FLAC__CPU_IA32
-		FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
-#ifdef FLAC__HAS_NASM
-		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.x86.mmx) {
-			decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
-			decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
-		}
-		else {
-			decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
-			decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
-		}
-#endif
-#if FLAC__HAS_X86INTRIN && ! defined FLAC__INTEGER_ONLY_LIBRARY
-# if defined FLAC__SSE4_1_SUPPORTED
-		if (decoder->private_->cpuinfo.x86.sse41) {
-#  if !defined FLAC__HAS_NASM  /* these are not undoubtedly faster than their MMX ASM counterparts */
-			decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_intrin_sse41;
-			decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse41;
-#  endif
-			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
-
 	/* from here on, errors are fatal */
 
 	if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) {
@@ -663,6 +621,10 @@
 			decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
 		}
 	}
+	if(0 != decoder->private_->side_subframe) {
+		free(decoder->private_->side_subframe);
+		decoder->private_->side_subframe = 0;
+	}
 	decoder->private_->output_capacity = 0;
 	decoder->private_->output_channels = 0;
 
@@ -915,6 +877,11 @@
 	return true;
 }
 
+FLAC_API const void *FLAC__stream_decoder_get_client_data(FLAC__StreamDecoder *decoder)
+{
+	return decoder->private_->client_data;
+}
+
 FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
 {
 	FLAC__ASSERT(0 != decoder);
@@ -926,6 +893,7 @@
 
 	decoder->private_->samples_decoded = 0;
 	decoder->private_->do_md5_checking = false;
+	decoder->private_->last_seen_framesync = 0;
 
 #if FLAC__HAS_OGG
 	if(decoder->private_->is_ogg)
@@ -969,8 +937,6 @@
 		if(decoder->private_->seek_callback && decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR)
 			return false; /* seekable and seek fails, reset fails */
 	}
-	else
-		decoder->private_->internal_reset_hack = false;
 
 	decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
 
@@ -993,10 +959,19 @@
 	 * FLAC__stream_decoder_finish() to make sure things are always cleaned up
 	 * properly.
 	 */
+	if(!decoder->private_->internal_reset_hack) {
+		/* Only finish MD5 context when it has been initialized
+		 * (i.e. when internal_reset_hack is not set) */
+		FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
+	}
+	else
+		decoder->private_->internal_reset_hack = false;
 	FLAC__MD5Init(&decoder->private_->md5context);
 
 	decoder->private_->first_frame_offset = 0;
 	decoder->private_->unparseable_frame_count = 0;
+	decoder->private_->last_seen_framesync = 0;
+	decoder->private_->last_frame_is_set = false;
 
 	return true;
 }
@@ -1259,12 +1234,13 @@
 	return stdin;
 }
 
-FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels)
+FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps)
 {
 	uint32_t i;
 	FLAC__int32 *tmp;
 
-	if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels)
+	if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels &&
+	   (bps < 32 || decoder->private_->side_subframe != 0))
 		return true;
 
 	/* simply using realloc() is not practical because the number of channels may change mid-stream */
@@ -1280,6 +1256,11 @@
 		}
 	}
 
+	if(0 != decoder->private_->side_subframe) {
+		free(decoder->private_->side_subframe);
+		decoder->private_->side_subframe = 0;
+	}
+
 	for(i = 0; i < channels; i++) {
 		/* WATCHOUT:
 		 * FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN()
@@ -1301,6 +1282,14 @@
 		}
 	}
 
+	if(bps == 32) {
+		decoder->private_->side_subframe = safe_malloc_mul_2op_p(sizeof(FLAC__int64), /*times (*/size);
+		if(decoder->private_->side_subframe == NULL) {
+			decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+			return false;
+		}
+	}
+
 	decoder->private_->output_capacity = size;
 	decoder->private_->output_channels = channels;
 
@@ -1455,6 +1444,7 @@
 		}
 		else {
 			FLAC__bool ok = true;
+			FLAC__bitreader_set_limit(decoder->private_->input, real_length*8);
 			switch(type) {
 				case FLAC__METADATA_TYPE_PADDING:
 					/* skip the padding bytes */
@@ -1503,6 +1493,16 @@
 						block.data.unknown.data = 0;
 					break;
 			}
+			if(FLAC__bitreader_limit_remaining(decoder->private_->input) > 0) {
+				/* Content in metadata block didn't fit in block length
+				 * We cannot know whether the length or the content was
+				 * corrupt, so stop parsing metadata */
+				send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA);
+				if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_METADATA)
+					decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+				ok = false;
+			}
+			FLAC__bitreader_remove_limit(decoder->private_->input);
 			if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback)
 				decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
 
@@ -1525,7 +1525,7 @@
 						free(block.data.vorbis_comment.comments);
 					break;
 				case FLAC__METADATA_TYPE_CUESHEET:
-					if(block.data.cue_sheet.num_tracks > 0)
+					if(block.data.cue_sheet.num_tracks > 0 && 0 != block.data.cue_sheet.tracks)
 						for(i = 0; i < block.data.cue_sheet.num_tracks; i++)
 							if(0 != block.data.cue_sheet.tracks[i].indices)
 								free(block.data.cue_sheet.tracks[i].indices);
@@ -1877,11 +1877,18 @@
 	/* read type */
 	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN))
 		return false; /* read_callback_ sets the state for us */
-	obj->type = x;
+	if(x < FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED)
+		obj->type = x;
+	else
+		obj->type = FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER;
 
 	/* read MIME type */
 	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
 		return false; /* read_callback_ sets the state for us */
+	if(FLAC__bitreader_limit_remaining(decoder->private_->input) < x){
+		FLAC__bitreader_limit_invalidate(decoder->private_->input);
+		return false;
+	}
 	if(0 == (obj->mime_type = safe_malloc_add_2op_(x, /*+*/1))) {
 		decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 		return false;
@@ -1895,6 +1902,10 @@
 	/* read description */
 	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
 		return false; /* read_callback_ sets the state for us */
+	if(FLAC__bitreader_limit_remaining(decoder->private_->input) < x){
+		FLAC__bitreader_limit_invalidate(decoder->private_->input);
+		return false;
+	}
 	if(0 == (obj->description = safe_malloc_add_2op_(x, /*+*/1))) {
 		decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 		return false;
@@ -1924,6 +1935,10 @@
 	/* read data */
 	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
 		return false; /* read_callback_ sets the state for us */
+	if(FLAC__bitreader_limit_remaining(decoder->private_->input) < obj->data_length){
+		FLAC__bitreader_limit_invalidate(decoder->private_->input);
+		return false;
+	}
 	if(0 == (obj->data = safe_malloc_(obj->data_length))) {
 		decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 		return false;
@@ -1963,15 +1978,6 @@
 	FLAC__uint32 x;
 	FLAC__bool first = true;
 
-	/* If we know the total number of samples in the stream, stop if we've read that many. */
-	/* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
-	if(FLAC__stream_decoder_get_total_samples(decoder) > 0) {
-		if(decoder->private_->samples_decoded >= FLAC__stream_decoder_get_total_samples(decoder)) {
-			decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
-			return true;
-		}
-	}
-
 	/* make sure we're byte aligned */
 	if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) {
 		if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input)))
@@ -2001,6 +2007,12 @@
 			else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */
 				decoder->private_->header_warmup[1] = (FLAC__byte)x;
 				decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
+
+				/* Save location so we can rewind in case the frame turns
+				 * out to be invalid after the header */
+				FLAC__bitreader_set_framesync_location(decoder->private_->input);
+				if(!FLAC__stream_decoder_get_decode_position(decoder, &decoder->private_->last_seen_framesync))
+					decoder->private_->last_seen_framesync = 0;
 				return true;
 			}
 		}
@@ -2017,11 +2029,11 @@
 {
 	uint32_t channel;
 	uint32_t i;
-	FLAC__int32 mid, side;
 	uint32_t frame_crc; /* the one we calculate from the input stream */
 	FLAC__uint32 x;
 
 	*got_a_frame = false;
+	decoder->private_->side_subframe_in_use = false;
 
 	/* init the CRC */
 	frame_crc = 0;
@@ -2033,7 +2045,7 @@
 		return false;
 	if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means we didn't sync on a valid header */
 		return true;
-	if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels))
+	if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels, decoder->private_->frame.header.bits_per_sample))
 		return false;
 	for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
 		/*
@@ -2065,98 +2077,168 @@
 		/*
 		 * now read it
 		 */
-		if(!read_subframe_(decoder, channel, bps, do_full_decode))
-			return false;
-		if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
-			return true;
+		if(!read_subframe_(decoder, channel, bps, do_full_decode)){
+			/* read_callback_ sets the state for us */
+			if(decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
+				break;
+			else
+				return false;
+		}
 	}
-	if(!read_zero_padding_(decoder))
-		return false;
-	if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */
-		return true;
 
+	if(decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM)
+		if(!read_zero_padding_(decoder))
+			return false;
+
 	/*
 	 * Read the frame CRC-16 from the footer and check
 	 */
-	frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input);
-	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN))
-		return false; /* read_callback_ sets the state for us */
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-	if(1){
-#else
-	if(frame_crc == x) {
+	if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) {
+		frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input);
+		if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN)) {
+			/* read_callback_ sets the state for us */
+			if(decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM)
+				return false;
+		}
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+	}
+	if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME && frame_crc == x) {
 #endif
 		if(do_full_decode) {
 			/* Undo any special channel coding */
-			switch(decoder->private_->frame.header.channel_assignment) {
-				case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
-					/* do nothing */
-					break;
-				case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
-					FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
-					for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
-						decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i];
-					break;
-				case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
-					FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
-					for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
-						decoder->private_->output[0][i] += decoder->private_->output[1][i];
-					break;
-				case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
-					FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
-					for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
-#if 1
-						mid = decoder->private_->output[0][i];
-						side = decoder->private_->output[1][i];
-						mid = ((uint32_t) mid) << 1;
-						mid |= (side & 1); /* i.e. if 'side' is odd... */
-						decoder->private_->output[0][i] = (mid + side) >> 1;
-						decoder->private_->output[1][i] = (mid - side) >> 1;
-#else
-						/* OPT: without 'side' temp variable */
-						mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */
-						decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1;
-						decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1;
-#endif
+			undo_channel_coding(decoder);
+			/* Check whether decoded data actually fits bps */
+			for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
+				for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
+					int shift_bits = 32 - decoder->private_->frame.header.bits_per_sample;
+					/* Check whether shift_bits MSBs are 'empty' by shifting up and down */
+					if((decoder->private_->output[channel][i] < (INT32_MIN >> shift_bits)) ||
+					   (decoder->private_->output[channel][i] > (INT32_MAX >> shift_bits))) {
+						/* Bad frame, emit error */
+						send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH);
+						decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+						break;
 					}
-					break;
-				default:
-					FLAC__ASSERT(0);
-					break;
+				}
 			}
 		}
 	}
-	else {
-		/* Bad frame, emit error and zero the output signal */
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+	else if (decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) {
+		/* Bad frame, emit error */
 		send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH);
-		if(do_full_decode) {
-			for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
-				memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
+		decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+	}
+#endif
+
+	/* Check whether frames are missing, if so, add silence to compensate */
+	if(decoder->private_->last_frame_is_set && decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME && !decoder->private_->is_seeking && do_full_decode) {
+		FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
+		FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
+		if(decoder->private_->last_frame.header.number.sample_number + decoder->private_->last_frame.header.blocksize < decoder->private_->frame.header.number.sample_number) {
+			uint32_t padding_samples_needed = decoder->private_->frame.header.number.sample_number - (decoder->private_->last_frame.header.number.sample_number + decoder->private_->last_frame.header.blocksize);
+
+			/* Do some extra validation to assure last frame an current frame
+			 * header are both valid before adding silence inbetween
+			 * Technically both frames could be valid with differing sample_rates,
+			 * channels and bits_per_sample, but it is quite rare */
+			if(decoder->private_->last_frame.header.sample_rate == decoder->private_->frame.header.sample_rate &&
+			   decoder->private_->last_frame.header.channels == decoder->private_->frame.header.channels &&
+			   decoder->private_->last_frame.header.bits_per_sample == decoder->private_->frame.header.bits_per_sample &&
+			   decoder->private_->last_frame.header.blocksize >= 16) {
+
+				FLAC__Frame empty_frame;
+				empty_frame.header = decoder->private_->last_frame.header;
+				empty_frame.footer.crc = 0;
+				/* No repairs larger than 5 seconds or 50 frames are made, to not
+				 * unexpectedly create enormous files when one of the headers was
+				 * corrupt after all */
+				if(padding_samples_needed > (5*empty_frame.header.sample_rate))
+					padding_samples_needed = 5*empty_frame.header.sample_rate;
+				if(padding_samples_needed > (50*empty_frame.header.blocksize))
+					padding_samples_needed = 50*empty_frame.header.blocksize;
+				while(padding_samples_needed){
+					empty_frame.header.number.sample_number += empty_frame.header.blocksize;
+					if(padding_samples_needed < empty_frame.header.blocksize)
+						empty_frame.header.blocksize = padding_samples_needed;
+					padding_samples_needed -= empty_frame.header.blocksize;
+					decoder->protected_->blocksize = empty_frame.header.blocksize;
+
+					FLAC__ASSERT(empty_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
+					decoder->private_->samples_decoded = empty_frame.header.number.sample_number + empty_frame.header.blocksize;
+
+					if(!allocate_output_(decoder, empty_frame.header.blocksize, empty_frame.header.channels, empty_frame.header.bits_per_sample))
+						return false;
+
+					for(channel = 0; channel < empty_frame.header.channels; channel++) {
+						empty_frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT;
+						empty_frame.subframes[channel].data.constant.value = 0;
+						empty_frame.subframes[channel].wasted_bits = 0;
+						memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * empty_frame.header.blocksize);
+					}
+
+					if(write_audio_frame_to_client_(decoder, &empty_frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) {
+						decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
+						return false;
+					}
+				}
 			}
 		}
 	}
 
-	*got_a_frame = true;
+	if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC || decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) {
+		/* Got corruption, rewind if possible. Return value of seek
+		* isn't checked, if the seek fails the decoder will continue anyway */
+		if(!FLAC__bitreader_rewind_to_after_last_seen_framesync(decoder->private_->input)){
+#ifndef NDEBUG
+			fprintf(stderr, "Rewinding, seeking necessary\n");
+#endif
+			if(decoder->private_->seek_callback && decoder->private_->last_seen_framesync){
+				/* Last framesync isn't in bitreader anymore, rewind with seek if possible */
+#ifndef NDEBUG
+				FLAC__uint64 current_decode_position;
+				if(FLAC__stream_decoder_get_decode_position(decoder, &current_decode_position))
+					fprintf(stderr, "Bitreader was %lu bytes short\n", current_decode_position-decoder->private_->last_seen_framesync);
+#endif
+				if(decoder->private_->seek_callback(decoder, decoder->private_->last_seen_framesync, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR) {
+					decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
+					return false;
+				}
+				if(!FLAC__bitreader_clear(decoder->private_->input)) {
+					decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+					return false;
+				}
+			}
+		}
+#ifndef NDEBUG
+		else{
+			fprintf(stderr, "Rewinding, seeking not necessary\n");
+		}
+#endif
+	}
+	else {
+		*got_a_frame = true;
 
-	/* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */
-	if(decoder->private_->next_fixed_block_size)
-		decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size;
+		/* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */
+		if(decoder->private_->next_fixed_block_size)
+			decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size;
 
-	/* put the latest values into the public section of the decoder instance */
-	decoder->protected_->channels = decoder->private_->frame.header.channels;
-	decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
-	decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample;
-	decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate;
-	decoder->protected_->blocksize = decoder->private_->frame.header.blocksize;
+		/* put the latest values into the public section of the decoder instance */
+		decoder->protected_->channels = decoder->private_->frame.header.channels;
+		decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
+		decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample;
+		decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate;
+		decoder->protected_->blocksize = decoder->private_->frame.header.blocksize;
 
-	FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
-	decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize;
+		FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
+		decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize;
 
-	/* write it */
-	if(do_full_decode) {
-		if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) {
-			decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
-			return false;
+		/* write it */
+		if(do_full_decode) {
+			if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) {
+				decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
+				return false;
+			}
 		}
 	}
 
@@ -2341,6 +2423,9 @@
 		case 2:
 			decoder->private_->frame.header.bits_per_sample = 12;
 			break;
+		case 3:
+			is_unparseable = true;
+			break;
 		case 4:
 			decoder->private_->frame.header.bits_per_sample = 16;
 			break;
@@ -2350,9 +2435,8 @@
 		case 6:
 			decoder->private_->frame.header.bits_per_sample = 24;
 			break;
-		case 3:
 		case 7:
-			is_unparseable = true;
+			decoder->private_->frame.header.bits_per_sample = 32;
 			break;
 		default:
 			FLAC__ASSERT(0);
@@ -2359,11 +2443,6 @@
 			break;
 	}
 
-	if(decoder->private_->frame.header.bits_per_sample == 32 && decoder->private_->frame.header.channel_assignment != FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT){
-		/* Decoder isn't equipped for 33-bit side frame */
-		is_unparseable = true;
-	}
-
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 	/* check to make sure that reserved bit is 0 */
 	if(raw_header[3] & 0x01) /* MAGIC NUMBER */
@@ -2529,12 +2608,6 @@
 	}
 	else if(x <= 24) {
 		uint32_t predictor_order = (x>>1)&7;
-		if(decoder->private_->frame.header.bits_per_sample > 24){
-			/* Decoder isn't equipped for fixed subframes with more than 24 bps */
-			send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
-			decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
-			return true;
-		}
 		if(decoder->private_->frame.header.blocksize <= predictor_order){
 			send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
 			decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
@@ -2565,10 +2638,22 @@
 
 	if(wasted_bits && do_full_decode) {
 		x = decoder->private_->frame.subframes[channel].wasted_bits;
-		for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
-			uint32_t val = decoder->private_->output[channel][i];
-			decoder->private_->output[channel][i] = (val << x);
+		if((bps + x) < 33) {
+			for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
+				uint32_t val = decoder->private_->output[channel][i];
+				decoder->private_->output[channel][i] = (val << x);
+			}
 		}
+		else {
+			/* When there are wasted bits, bps is never 33 and so
+			 * side_subframe is never already in use */
+			FLAC__ASSERT(!decoder->private_->side_subframe_in_use);
+			decoder->private_->side_subframe_in_use = true;
+			for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
+				uint64_t val = decoder->private_->output[channel][i];
+				decoder->private_->side_subframe[i] = (val << x);
+			}
+		}
 	}
 
 	return true;
@@ -2577,13 +2662,12 @@
 FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode)
 {
 	FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant;
-	FLAC__int32 x;
+	FLAC__int64 x;
 	uint32_t i;
-	FLAC__int32 *output = decoder->private_->output[channel];
 
 	decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT;
 
-	if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps))
+	if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &x, bps))
 		return false; /* read_callback_ sets the state for us */
 
 	subframe->value = x;
@@ -2590,8 +2674,16 @@
 
 	/* decode the subframe */
 	if(do_full_decode) {
-		for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
-			output[i] = x;
+		if(bps <= 32) {
+			FLAC__int32 *output = decoder->private_->output[channel];
+			for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
+				output[i] = x;
+		} else {
+			FLAC__int64 *output = decoder->private_->side_subframe;
+			decoder->private_->side_subframe_in_use = true;
+			for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
+				output[i] = x;
+		}
 	}
 
 	return true;
@@ -2600,7 +2692,7 @@
 FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode)
 {
 	FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed;
-	FLAC__int32 i32;
+	FLAC__int64 i64;
 	FLAC__uint32 u32;
 	uint32_t u;
 
@@ -2611,9 +2703,9 @@
 
 	/* read warm-up samples */
 	for(u = 0; u < order; u++) {
-		if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps))
+		if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &i64, bps))
 			return false; /* read_callback_ sets the state for us */
-		subframe->warmup[u] = i32;
+		subframe->warmup[u] = i64;
 	}
 
 	/* read entropy coding method info */
@@ -2653,8 +2745,19 @@
 
 	/* decode the subframe */
 	if(do_full_decode) {
-		memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
-		FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order);
+		if(bps < 33){
+			for(uint32_t i = 0; i < order; i++)
+				decoder->private_->output[channel][i] = subframe->warmup[i];
+			if(bps+order <= 32)
+				FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order);
+			else
+				FLAC__fixed_restore_signal_wide(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order);
+		}
+		else {
+			decoder->private_->side_subframe_in_use = true;
+			memcpy(decoder->private_->side_subframe, subframe->warmup, sizeof(FLAC__int64) * order);
+			FLAC__fixed_restore_signal_wide_33bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->side_subframe+order);
+		}
 	}
 
 	return true;
@@ -2664,6 +2767,7 @@
 {
 	FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc;
 	FLAC__int32 i32;
+	FLAC__int64 i64;
 	FLAC__uint32 u32;
 	uint32_t u;
 
@@ -2674,9 +2778,9 @@
 
 	/* read warm-up samples */
 	for(u = 0; u < order; u++) {
-		if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps))
+		if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &i64, bps))
 			return false; /* read_callback_ sets the state for us */
-		subframe->warmup[u] = i32;
+		subframe->warmup[u] = i64;
 	}
 
 	/* read qlp coeff precision */
@@ -2743,14 +2847,20 @@
 
 	/* decode the subframe */
 	if(do_full_decode) {
-		memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
-		if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
-			if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
-				decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
+		if(bps <= 32) {
+			for(uint32_t i = 0; i < order; i++)
+				decoder->private_->output[channel][i] = subframe->warmup[i];
+			if(FLAC__lpc_max_residual_bps(bps, subframe->qlp_coeff, order, subframe->quantization_level) <= 32 &&
+			   FLAC__lpc_max_prediction_before_shift_bps(bps, subframe->qlp_coeff, order) <= 32)
+				FLAC__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
-				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
-			decoder->private_->local_lpc_restore_signal_64bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
+				FLAC__lpc_restore_signal_wide(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_->side_subframe_in_use = true;
+			memcpy(decoder->private_->side_subframe, subframe->warmup, sizeof(FLAC__int64) * order);
+			FLAC__lpc_restore_signal_wide_33bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->side_subframe+order);
+		}
 	}
 
 	return true;
@@ -2759,23 +2869,40 @@
 FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode)
 {
 	FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim;
-	FLAC__int32 x, *residual = decoder->private_->residual[channel];
 	uint32_t i;
 
 	decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM;
 
-	subframe->data = residual;
+	if(bps < 33) {
+		FLAC__int32 x, *residual = decoder->private_->residual[channel];
 
-	for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
-		if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps))
-			return false; /* read_callback_ sets the state for us */
-		residual[i] = x;
+		subframe->data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32;
+		subframe->data.int32 = residual;
+
+		for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
+			if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps))
+				return false; /* read_callback_ sets the state for us */
+			residual[i] = x;
+		}
+
+		/* decode the subframe */
+		if(do_full_decode)
+			memcpy(decoder->private_->output[channel], subframe->data.int32, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
 	}
+	else {
+		FLAC__int64 x, *side = decoder->private_->side_subframe;
 
-	/* decode the subframe */
-	if(do_full_decode)
-		memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
+		subframe->data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64;
+		subframe->data.int64 = side;
+		decoder->private_->side_subframe_in_use = true;
 
+		for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
+			if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &x, bps))
+				return false; /* read_callback_ sets the state for us */
+			side[i] = x;
+		}
+	}
+
 	return true;
 }
 
@@ -2805,8 +2932,17 @@
 		if(rice_parameter < pesc) {
 			partitioned_rice_contents->raw_bits[partition] = 0;
 			u = (partition == 0) ? partition_samples - predictor_order : partition_samples;
-			if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter))
-				return false; /* read_callback_ sets the state for us */
+			if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)){
+				if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) {
+					/* no error was set, read_callback_ didn't set it, so
+					 * invalid rice symbol was found */
+					send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
+					decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+					return true;
+				}
+				else
+					return false; /* read_callback_ sets the state for us */
+			}
 			sample += u;
 		}
 		else {
@@ -2813,11 +2949,17 @@
 			if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
 				return false; /* read_callback_ sets the state for us */
 			partitioned_rice_contents->raw_bits[partition] = rice_parameter;
-			for(u = (partition == 0)? predictor_order : 0; u < partition_samples; u++, sample++) {
-				if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter))
-					return false; /* read_callback_ sets the state for us */
-				residual[sample] = i;
+			if(rice_parameter == 0) {
+				for(u = (partition == 0)? predictor_order : 0; u < partition_samples; u++, sample++)
+					residual[sample] = 0;
 			}
+			else{
+				for(u = (partition == 0)? predictor_order : 0; u < partition_samples; u++, sample++) {
+					if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter))
+						return false; /* read_callback_ sets the state for us */
+					residual[sample] = i;
+				}
+			}
 		}
 	}
 
@@ -2920,6 +3062,65 @@
 	 */
 }
 
+#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
+/* The attribute below is to silence the undefined sanitizer of oss-fuzz.
+ * Because fuzzing feeds bogus predictors and residual samples to the
+ * decoder, having overflows in this section is unavoidable. Also,
+ * because the calculated values are audio path only, there is no
+ * potential for security problems */
+__attribute__((no_sanitize("signed-integer-overflow")))
+#endif
+void undo_channel_coding(FLAC__StreamDecoder *decoder) {
+	switch(decoder->private_->frame.header.channel_assignment) {
+	case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
+		/* do nothing */
+		break;
+	case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
+		FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
+		FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32));
+		for(uint32_t i = 0; i < decoder->private_->frame.header.blocksize; i++)
+			if(decoder->private_->side_subframe_in_use)
+				decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->side_subframe[i];
+			else
+				decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i];
+		break;
+	case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
+		FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
+		FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32));
+		for(uint32_t i = 0; i < decoder->private_->frame.header.blocksize; i++)
+			if(decoder->private_->side_subframe_in_use)
+				decoder->private_->output[0][i] = decoder->private_->output[1][i] + decoder->private_->side_subframe[i];
+			else
+				decoder->private_->output[0][i] += decoder->private_->output[1][i];
+		break;
+	case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
+		FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
+		FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32));
+		for(uint32_t i = 0; i < decoder->private_->frame.header.blocksize; i++) {
+			if(!decoder->private_->side_subframe_in_use){
+				FLAC__int32 mid, side;
+				mid = decoder->private_->output[0][i];
+				side = decoder->private_->output[1][i];
+				mid = ((uint32_t) mid) << 1;
+				mid |= (side & 1); /* i.e. if 'side' is odd... */
+				decoder->private_->output[0][i] = (mid + side) >> 1;
+				decoder->private_->output[1][i] = (mid - side) >> 1;
+			}
+			else { /* bps == 32 */
+				FLAC__int64 mid;
+				mid = ((uint64_t)decoder->private_->output[0][i]) << 1;
+				mid |= (decoder->private_->side_subframe[i] & 1); /* i.e. if 'side' is odd... */
+				decoder->private_->output[0][i] = (mid + decoder->private_->side_subframe[i]) >> 1;
+				decoder->private_->output[1][i] = (mid - decoder->private_->side_subframe[i]) >> 1;
+			}
+		}
+		break;
+	default:
+		FLAC__ASSERT(0);
+		break;
+	}
+}
+
 #if FLAC__HAS_OGG
 FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes)
 {
@@ -2968,6 +3169,8 @@
 
 FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
 {
+	decoder->private_->last_frame = *frame; /* save the frame */
+	decoder->private_->last_frame_is_set = true;
 	if(decoder->private_->is_seeking) {
 		FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
 		FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
@@ -2978,7 +3181,6 @@
 #if FLAC__HAS_OGG
 		decoder->private_->got_a_frame = true;
 #endif
-		decoder->private_->last_frame = *frame; /* save the frame */
 		if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
 			uint32_t delta = (uint32_t)(target_sample - this_frame_sample);
 			/* kick out of seek mode */
@@ -3032,7 +3234,7 @@
 	FLAC__int64 pos = -1;
 	int i;
 	uint32_t approx_bytes_per_frame;
-	FLAC__bool first_seek = true;
+	FLAC__bool first_seek = true, seek_from_lower_bound = false;
 	const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder);
 	const uint32_t min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize;
 	const uint32_t max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize;
@@ -3077,7 +3279,8 @@
 	upper_bound = stream_length;
 	upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/;
 
-	if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) {
+	if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC &&
+	   decoder->private_->samples_decoded != 0) {
 		if(target_sample < decoder->private_->samples_decoded) {
 			if(FLAC__stream_decoder_get_decode_position(decoder, &upper_bound))
 				upper_bound_sample = decoder->private_->samples_decoded;
@@ -3093,7 +3296,9 @@
 	 * must be ordered by ascending sample number.
 	 *
 	 * Note: to protect against invalid seek tables we will ignore points
-	 * that have frame_samples==0 or sample_number>=total_samples
+	 * that have frame_samples==0 or sample_number>=total_samples. Also,
+	 * because math is limited to 64-bit ints, seekpoints with an offset
+	 * larger than 2^63 (8 exbibyte) are rejected.
 	 */
 	if(seek_table) {
 		FLAC__uint64 new_lower_bound = lower_bound;
@@ -3154,22 +3359,34 @@
 
 	decoder->private_->target_sample = target_sample;
 	while(1) {
+		/* check whether decoder is still valid so bad state isn't overwritten
+		 * with seek error */
+		if(decoder->protected_->state == FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ||
+		   decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED)
+			return false;
 		/* check if the bounds are still ok */
-		if (lower_bound_sample >= upper_bound_sample || lower_bound > upper_bound) {
+		if (lower_bound_sample >= upper_bound_sample ||
+		    lower_bound > upper_bound ||
+		    upper_bound >= INT64_MAX) {
 			decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
 			return false;
 		}
+		if(seek_from_lower_bound) {
+			pos = lower_bound;
+		}
+		else {
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
-		pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(target_sample - lower_bound_sample) / (double)(upper_bound_sample - lower_bound_sample) * (double)(upper_bound - lower_bound)) - approx_bytes_per_frame;
+			pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(target_sample - lower_bound_sample) / (double)(upper_bound_sample - lower_bound_sample) * (double)(upper_bound - lower_bound)) - approx_bytes_per_frame;
 #else
-		/* a little less accurate: */
-		if(upper_bound - lower_bound < 0xffffffff)
-			pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame;
-		else { /* @@@ WATCHOUT, ~2TB limit */
-		        FLAC__uint64 ratio = (1<<16) / (upper_bound_sample - lower_bound_sample);
-			pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8) * ratio)) - approx_bytes_per_frame;
-		}
+			/* a little less accurate: */
+			if(upper_bound - lower_bound < 0xffffffff)
+				pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame;
+			else { /* @@@ WATCHOUT, ~2TB limit */
+			        FLAC__uint64 ratio = (1<<16) / (upper_bound_sample - lower_bound_sample);
+				pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8) * ratio)) - approx_bytes_per_frame;
+			}
 #endif
+		}
 		if(pos >= (FLAC__int64)upper_bound)
 			pos = (FLAC__int64)upper_bound - 1;
 		if(pos < (FLAC__int64)lower_bound)
@@ -3189,18 +3406,25 @@
 		 * FLAC__stream_decoder_process_single() to return false.
 		 */
 		decoder->private_->unparseable_frame_count = 0;
-		if(!FLAC__stream_decoder_process_single(decoder) ||
-		   decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) {
-			decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
-			return false;
+		if(!FLAC__stream_decoder_process_single(decoder) || decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED || 0 == decoder->private_->samples_decoded) {
+			/* No frame could be decoded */
+			if(decoder->protected_->state != FLAC__STREAM_DECODER_ABORTED && decoder->private_->eof_callback(decoder, decoder->private_->client_data) && !seek_from_lower_bound){
+				/* decoder has hit end of stream while processing corrupt
+				 * frame. To remedy this, try decoding a frame at the lower
+				 * bound so the seek after that hopefully ends up somewhere
+				 * else */
+				seek_from_lower_bound = true;
+				continue;
+			}
+			else {
+				decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
+				return false;
+			}
 		}
+		seek_from_lower_bound = false;
+
 		/* our write callback will change the state when it gets to the target frame */
 		/* actually, we could have got_a_frame if our decoder is at FLAC__STREAM_DECODER_END_OF_STREAM so we need to check for that also */
-#if 0
-		/*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */
-		if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM)
-			break;
-#endif
 		if(!decoder->private_->is_seeking)
 			break;
 
@@ -3207,7 +3431,7 @@
 		FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
 		this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
 
-		if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) {
+		if(this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek) {
 			if (pos == (FLAC__int64)lower_bound) {
 				/* can't move back any more than the first frame, something is fatally wrong */
 				decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
@@ -3281,6 +3505,12 @@
 
 	decoder->private_->target_sample = target_sample;
 	for( ; ; iteration++) {
+		/* Do sanity checks on bounds */
+		if(right_pos <= left_pos || right_pos - left_pos < 9) {
+			/* FLAC frame is at least 9 byte in size */
+			decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
+			return false;
+		}
 		if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
 			if (iteration >= BINARY_SEARCH_AFTER_ITERATION) {
 				pos = (right_pos + left_pos) / 2;
@@ -3433,7 +3663,13 @@
 
 	if(decoder->private_->file == stdin)
 		return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
-	else if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0)
+
+#ifndef FLAC__USE_FILELENGTHI64
+	if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0)
+#else
+	filestats.st_size = _filelengthi64(fileno(decoder->private_->file));
+	if(filestats.st_size < 0)
+#endif
 		return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
 	else {
 		*stream_length = (FLAC__uint64)filestats.st_size;
@@ -3446,9 +3682,4 @@
 	(void)client_data;
 
 	return feof(decoder->private_->file)? true : false;
-}
-
-void *get_client_data_from_decoder(FLAC__StreamDecoder *decoder)
-{
-	return decoder->private_->client_data;
 }
--- a/sys/src/cmd/audio/libFLAC/stream_encoder.c
+++ b/sys/src/cmd/audio/libFLAC/stream_encoder.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -118,9 +118,9 @@
 	{ false, false,  6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
 	{ true , true ,  8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
 	{ true , false,  8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" },
-	{ true , false,  8, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
-	{ true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
-	{ true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2);punchout_tukey(3)" }
+	{ true , false,  8, 0, false, false, false, 0, 6, 0, "subdivide_tukey(2)" },
+	{ true , false, 12, 0, false, false, false, 0, 6, 0, "subdivide_tukey(2)" },
+	{ true , false, 12, 0, false, false, false, 0, 6, 0, "subdivide_tukey(3)" }
 	/* here we use locale-independent 5e-1 instead of 0.5 or 0,5 */
 };
 
@@ -140,8 +140,8 @@
 #if FLAC__HAS_OGG
 static void update_ogg_metadata_(FLAC__StreamEncoder *encoder);
 #endif
-static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block);
-static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block);
+static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block);
+static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder);
 
 static FLAC__bool process_subframe_(
 	FLAC__StreamEncoder *encoder,
@@ -149,7 +149,7 @@
 	uint32_t max_partition_order,
 	const FLAC__FrameHeader *frame_header,
 	uint32_t subframe_bps,
-	const FLAC__int32 integer_signal[],
+	const void *integer_signal,
 	FLAC__Subframe *subframe[2],
 	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
 	FLAC__int32 *residual[2],
@@ -167,7 +167,7 @@
 
 static uint32_t evaluate_constant_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal,
+	const FLAC__int64 signal,
 	uint32_t blocksize,
 	uint32_t subframe_bps,
 	FLAC__Subframe *subframe
@@ -175,7 +175,7 @@
 
 static uint32_t evaluate_fixed_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal[],
+	const void *signal,
 	FLAC__int32 residual[],
 	FLAC__uint64 abs_residual_partition_sums[],
 	uint32_t raw_bits_per_partition[],
@@ -182,7 +182,6 @@
 	uint32_t blocksize,
 	uint32_t subframe_bps,
 	uint32_t order,
-	uint32_t rice_parameter,
 	uint32_t rice_parameter_limit,
 	uint32_t min_partition_order,
 	uint32_t max_partition_order,
@@ -195,7 +194,7 @@
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 static uint32_t evaluate_lpc_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal[],
+	const void *signal,
 	FLAC__int32 residual[],
 	FLAC__uint64 abs_residual_partition_sums[],
 	uint32_t raw_bits_per_partition[],
@@ -204,7 +203,6 @@
 	uint32_t subframe_bps,
 	uint32_t order,
 	uint32_t qlp_coeff_precision,
-	uint32_t rice_parameter,
 	uint32_t rice_parameter_limit,
 	uint32_t min_partition_order,
 	uint32_t max_partition_order,
@@ -217,7 +215,7 @@
 
 static uint32_t evaluate_verbatim_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal[],
+	const void *signal,
 	uint32_t blocksize,
 	uint32_t subframe_bps,
 	FLAC__Subframe *subframe
@@ -230,7 +228,6 @@
 	uint32_t raw_bits_per_partition[],
 	uint32_t residual_samples,
 	uint32_t predictor_order,
-	uint32_t rice_parameter,
 	uint32_t rice_parameter_limit,
 	uint32_t min_partition_order,
 	uint32_t max_partition_order,
@@ -267,7 +264,6 @@
 	const uint32_t raw_bits_per_partition[],
 	const uint32_t residual_samples,
 	const uint32_t predictor_order,
-	const uint32_t suggested_rice_parameter,
 	const uint32_t rice_parameter_limit,
 	const uint32_t rice_parameter_search_dist,
 	const uint32_t partition_order,
@@ -277,6 +273,7 @@
 );
 
 static uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples);
+static uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples);
 
 /* verify-related routines: */
 static void append_to_verify_fifo_(
@@ -317,6 +314,7 @@
 	uint32_t input_capacity;                          /* current size (in samples) of the signal and residual buffers */
 	FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS];  /* the integer version of the input signal */
 	FLAC__int32 *integer_signal_mid_side[2];          /* the integer version of the mid-side input signal (stereo only) */
+	FLAC__int64 *integer_signal_33bit_side;           /* 33-bit side for 32-bit stereo decorrelation */
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 	FLAC__real *real_signal[FLAC__MAX_CHANNELS];      /* (@@@ currently unused) the floating-point version of the input signal */
 	FLAC__real *real_signal_mid_side[2];              /* (@@@ currently unused) the floating-point version of the mid-side input signal (stereo only) */
@@ -360,11 +358,17 @@
 	uint32_t (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
 #endif
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
-	void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]);
+	void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]);
 	void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
 	void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
 	void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
 #endif
+	FLAC__bool disable_mmx;
+	FLAC__bool disable_sse2;
+	FLAC__bool disable_ssse3;
+	FLAC__bool disable_sse41;
+	FLAC__bool disable_avx2;
+	FLAC__bool disable_fma;
 	FLAC__bool disable_constant_subframes;
 	FLAC__bool disable_fixed_subframes;
 	FLAC__bool disable_verbatim_subframes;
@@ -385,6 +389,7 @@
 	/* unaligned (original) pointers to allocated data */
 	FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS];
 	FLAC__int32 *integer_signal_mid_side_unaligned[2];
+	FLAC__int64 *integer_signal_33bit_side_unaligned;
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 	FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) */
 	FLAC__real *real_signal_mid_side_unaligned[2]; /* (@@@ currently unused) */
@@ -536,6 +541,8 @@
 
 	encoder->private_->file = 0;
 
+	encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
+
 	set_defaults_(encoder);
 
 	encoder->private_->is_being_deleted = false;
@@ -568,8 +575,6 @@
 	for(i = 0; i < 2; i++)
 		FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_extra[i]);
 
-	encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
-
 	return encoder;
 }
 
@@ -649,10 +654,7 @@
 	else if(!encoder->protected_->do_mid_side_stereo)
 		encoder->protected_->loose_mid_side_stereo = false;
 
-	if(encoder->protected_->bits_per_sample >= 32)
-		encoder->protected_->do_mid_side_stereo = false; /* since we currently do 32-bit math, the side channel would have 33 bps and overflow */
-
-	if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE)
+	if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__MAX_BITS_PER_SAMPLE)
 		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE;
 
 	if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate))
@@ -719,7 +721,8 @@
 			encoder->protected_->bits_per_sample != 12 &&
 			encoder->protected_->bits_per_sample != 16 &&
 			encoder->protected_->bits_per_sample != 20 &&
-			encoder->protected_->bits_per_sample != 24
+			encoder->protected_->bits_per_sample != 24 &&
+			encoder->protected_->bits_per_sample != 32
 		)
 			return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
 		if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER)
@@ -832,6 +835,7 @@
 		encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0;
 #endif
 	}
+	encoder->private_->integer_signal_33bit_side_unaligned = encoder->private_->integer_signal_33bit_side = 0;
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 	for(i = 0; i < encoder->protected_->num_apodizations; i++)
 		encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0;
@@ -853,10 +857,10 @@
 	encoder->private_->loose_mid_side_stereo_frames = (uint32_t)((double)encoder->protected_->sample_rate * 0.4 / (double)encoder->protected_->blocksize + 0.5);
 #else
 	/* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */
-	/* sample rate can be up to 655350 Hz, and thus use 20 bits, so we do the multiply&divide by hand */
-	FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 655350);
+	/* sample rate can be up to 1048575 Hz, and thus use 20 bits, so we do the multiply&divide by hand */
+	FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 1048575);
 	FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535);
-	FLAC__ASSERT(encoder->protected_->sample_rate <= 655350);
+	FLAC__ASSERT(encoder->protected_->sample_rate <= 1048575);
 	FLAC__ASSERT(encoder->protected_->blocksize <= 65535);
 	encoder->private_->loose_mid_side_stereo_frames = (uint32_t)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF);
 #endif
@@ -870,6 +874,20 @@
 	 * get the CPU info and set the function pointers
 	 */
 	FLAC__cpu_info(&encoder->private_->cpuinfo);
+	/* remove cpu info as requested by
+	 * FLAC__stream_encoder_disable_instruction_set */
+	if(encoder->private_->disable_mmx)
+		encoder->private_->cpuinfo.x86.mmx = false;
+	if(encoder->private_->disable_sse2)
+		encoder->private_->cpuinfo.x86.sse2 = false;
+	if(encoder->private_->disable_ssse3)
+		encoder->private_->cpuinfo.x86.ssse3 = false;
+	if(encoder->private_->disable_sse41)
+		encoder->private_->cpuinfo.x86.sse41 = false;
+	if(encoder->private_->disable_avx2)
+		encoder->private_->cpuinfo.x86.avx2 = false;
+	if(encoder->private_->disable_fma)
+		encoder->private_->cpuinfo.x86.fma = false;
 	/* first default to the non-asm routines */
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 	encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
@@ -889,51 +907,49 @@
 #ifdef FLAC__HAS_TARGET_POWER8
 #ifdef FLAC__HAS_TARGET_POWER9
 	if (encoder->private_->cpuinfo.ppc.arch_3_00) {
-		if(encoder->protected_->max_lpc_order < 4)
-			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_4;
-		else if(encoder->protected_->max_lpc_order < 8)
+		if(encoder->protected_->max_lpc_order < 8)
 			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_8;
-		else if(encoder->protected_->max_lpc_order < 12)
-			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_12;
-		else if(encoder->protected_->max_lpc_order < 16)
-			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_16;
+		else if(encoder->protected_->max_lpc_order < 10)
+			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_10;
+		else if(encoder->protected_->max_lpc_order < 14)
+			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_14;
 		else
 			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
 	} else
 #endif
 	if (encoder->private_->cpuinfo.ppc.arch_2_07) {
-		if(encoder->protected_->max_lpc_order < 4)
-			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_4;
-		else if(encoder->protected_->max_lpc_order < 8)
+		if(encoder->protected_->max_lpc_order < 8)
 			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_8;
-		else if(encoder->protected_->max_lpc_order < 12)
-			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_12;
-		else if(encoder->protected_->max_lpc_order < 16)
-			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16;
+		else if(encoder->protected_->max_lpc_order < 10)
+			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_10;
+		else if(encoder->protected_->max_lpc_order < 14)
+			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_14;
 		else
 			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
 	}
 #endif
+#endif /* defined(FLAC__CPU_PPC64) && defined(FLAC__USE_VSX) */
+
+#if defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN
+#if FLAC__HAS_A64NEONINTRIN
+	if(encoder->protected_->max_lpc_order < 8)
+		encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_8;
+	else if(encoder->protected_->max_lpc_order < 10)
+		encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_10;
+	else if(encoder->protected_->max_lpc_order < 14)
+		encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14;
+	else
+		encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
 #endif
+    encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon;
+    encoder->private_->local_lpc_compute_residual_from_qlp_coefficients       = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon;
+    encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_neon;
+#endif /* defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN */
+
 	if(encoder->private_->cpuinfo.use_asm) {
 #  ifdef FLAC__CPU_IA32
 		FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
 #   ifdef FLAC__HAS_NASM
-		if (encoder->private_->cpuinfo.x86.sse) {
-			if(encoder->protected_->max_lpc_order < 4)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old;
-			else if(encoder->protected_->max_lpc_order < 8)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old;
-			else if(encoder->protected_->max_lpc_order < 12)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old;
-			else if(encoder->protected_->max_lpc_order < 16)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old;
-			else
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
-		}
-		else
-			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
-
 		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.x86.mmx) {
 			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
@@ -948,37 +964,15 @@
 			encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov;
 #   endif /* FLAC__HAS_NASM */
 #   if FLAC__HAS_X86INTRIN
-#    if defined FLAC__SSE_SUPPORTED
-		if (encoder->private_->cpuinfo.x86.sse) {
-			if (encoder->private_->cpuinfo.x86.sse42 || !encoder->private_->cpuinfo.x86.intel) { /* use new autocorrelation functions */
-				if(encoder->protected_->max_lpc_order < 4)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new;
-				else if(encoder->protected_->max_lpc_order < 8)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new;
-				else if(encoder->protected_->max_lpc_order < 12)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new;
-				else if(encoder->protected_->max_lpc_order < 16)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new;
-				else
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
-			}
-			else { /* use old autocorrelation functions */
-				if(encoder->protected_->max_lpc_order < 4)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old;
-				else if(encoder->protected_->max_lpc_order < 8)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old;
-				else if(encoder->protected_->max_lpc_order < 12)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old;
-				else if(encoder->protected_->max_lpc_order < 16)
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old;
-				else
-					encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
-			}
-		}
-#    endif
-
 #    ifdef FLAC__SSE2_SUPPORTED
 		if (encoder->private_->cpuinfo.x86.sse2) {
+			if(encoder->protected_->max_lpc_order < 8)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8;
+			else if(encoder->protected_->max_lpc_order < 10)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10;
+			else if(encoder->protected_->max_lpc_order < 14)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14;
+
 			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;
 		}
@@ -1013,32 +1007,18 @@
 #  elif defined FLAC__CPU_X86_64
 		FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64);
 #   if FLAC__HAS_X86INTRIN
-#    ifdef FLAC__SSE_SUPPORTED
-		if(encoder->private_->cpuinfo.x86.sse42 || !encoder->private_->cpuinfo.x86.intel) { /* use new autocorrelation functions */
-			if(encoder->protected_->max_lpc_order < 4)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new;
-			else if(encoder->protected_->max_lpc_order < 8)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new;
-			else if(encoder->protected_->max_lpc_order < 12)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new;
-			else if(encoder->protected_->max_lpc_order < 16)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new;
+#    ifdef FLAC__SSE2_SUPPORTED
+		if(encoder->private_->cpuinfo.x86.sse2) { /* For fuzzing */
+			if(encoder->protected_->max_lpc_order < 8)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8;
+			else if(encoder->protected_->max_lpc_order < 10)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10;
+			else if(encoder->protected_->max_lpc_order < 14)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14;
+
+			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2;
 		}
-		else {
-			if(encoder->protected_->max_lpc_order < 4)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old;
-			else if(encoder->protected_->max_lpc_order < 8)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old;
-			else if(encoder->protected_->max_lpc_order < 12)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old;
-			else if(encoder->protected_->max_lpc_order < 16)
-				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old;
-		}
 #    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;
@@ -1051,10 +1031,23 @@
 			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2;
 		}
 #    endif
+#    ifdef FLAC__FMA_SUPPORTED
+		if(encoder->private_->cpuinfo.x86.fma) {
+			if(encoder->protected_->max_lpc_order < 8)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_8;
+			else if(encoder->protected_->max_lpc_order < 12)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_12;
+			else if(encoder->protected_->max_lpc_order < 16)
+				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_16;
+		}
+#    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;
+		if(encoder->private_->cpuinfo.x86.sse2) { /* For fuzzing */
+			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) {
@@ -1066,6 +1059,7 @@
 #  endif /* FLAC__CPU_... */
 	}
 # endif /* !FLAC__NO_ASM */
+
 #endif /* !FLAC__INTEGER_ONLY_LIBRARY */
 #if !defined FLAC__NO_ASM && FLAC__HAS_X86INTRIN
 	if(encoder->private_->cpuinfo.use_asm) {
@@ -1475,14 +1469,24 @@
 	FLAC__ASSERT(0 != encoder->private_);
 	FLAC__ASSERT(0 != encoder->protected_);
 
-	if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED)
+	if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED){
+		if(encoder->protected_->metadata){ // True in case FLAC__stream_encoder_set_metadata was used but init failed
+			free(encoder->protected_->metadata);
+			encoder->protected_->metadata = 0;
+			encoder->protected_->num_metadata_blocks = 0;
+		}
+		if(0 != encoder->private_->file) {
+			if(encoder->private_->file != stdout)
+				fclose(encoder->private_->file);
+			encoder->private_->file = 0;
+		}
 		return true;
+	}
 
 	if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) {
 		if(encoder->private_->current_sample_number != 0) {
-			const FLAC__bool is_fractional_block = encoder->protected_->blocksize != encoder->private_->current_sample_number;
 			encoder->protected_->blocksize = encoder->private_->current_sample_number;
-			if(!process_frame_(encoder, is_fractional_block, /*is_last_block=*/true))
+			if(!process_frame_(encoder, /*is_last_block=*/true))
 				error = true;
 		}
 	}
@@ -1740,7 +1744,7 @@
 				encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
 			}
 		}
-		else if(n>15   && 0 == strncmp("partial_tukey("       , specification, 14)) {
+		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;
@@ -1761,7 +1765,7 @@
 				}
 			}
 		}
-		else if(n>16   && 0 == strncmp("punchout_tukey("       , specification, 15)) {
+		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;
@@ -1782,6 +1786,20 @@
 				}
 			}
 		}
+		else if(n>17  && 0 == strncmp("subdivide_tukey(", specification, 16)){
+			FLAC__int32 parts = (FLAC__int32)strtod(specification+16, 0);
+			if(parts > 1){
+				const char *si_1 = strchr(specification, '/');
+				FLAC__real p = si_1?(FLAC__real)strtod(si_1+1, 0):5e-1;
+				if(p > 1)
+					p = 1;
+				else if(p < 0)
+					p = 0;
+				encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.subdivide_tukey.parts = parts;
+				encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.subdivide_tukey.p = p/parts;
+				encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_SUBDIVIDE_TUKEY;
+			}
+		}
 		else if(n==5  && 0 == strncmp("welch"        , specification, n))
 			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH;
 		if (encoder->protected_->num_apodizations == 32)
@@ -1840,8 +1858,10 @@
 	FLAC__ASSERT(0 != encoder->protected_);
 	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
 		return false;
-#if 0
-	/*@@@ deprecated: */
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+	/* was deprecated since FLAC 1.0.4 (24-Sep-2002), but is needed for
+	 * full spec coverage, so this should be reenabled at some point.
+	 * For now only enable while fuzzing */
 	encoder->protected_->do_escape_coding = value;
 #else
 	(void)value;
@@ -1942,10 +1962,37 @@
 	return true;
 }
 
+FLAC_API FLAC__bool FLAC__stream_encoder_set_limit_min_bitrate(FLAC__StreamEncoder *encoder, FLAC__bool value)
+{
+	FLAC__ASSERT(0 != encoder);
+	FLAC__ASSERT(0 != encoder->private_);
+	FLAC__ASSERT(0 != encoder->protected_);
+	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
+		return false;
+	encoder->protected_->limit_min_bitrate = value;
+	return true;
+}
+
 /*
- * These three functions are not static, but not publicly exposed in
- * include/FLAC/ either.  They are used by the test suite.
+ * These four functions are not static, but not publicly exposed in
+ * include/FLAC/ either.  They are used by the test suite and in fuzzing
  */
+FLAC_API FLAC__bool FLAC__stream_encoder_disable_instruction_set(FLAC__StreamEncoder *encoder, FLAC__bool value)
+{
+	FLAC__ASSERT(0 != encoder);
+	FLAC__ASSERT(0 != encoder->private_);
+	FLAC__ASSERT(0 != encoder->protected_);
+	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
+		return false;
+	encoder->private_->disable_mmx = value & 1;
+	encoder->private_->disable_sse2 = value & 2;
+	encoder->private_->disable_ssse3 = value & 4;
+	encoder->private_->disable_sse41 = value & 8;
+	encoder->private_->disable_avx2 = value & 16;
+	encoder->private_->disable_fma = value & 32;
+	return true;
+}
+
 FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
 {
 	FLAC__ASSERT(0 != encoder);
@@ -2172,16 +2219,28 @@
 	return encoder->protected_->total_samples_estimate;
 }
 
+FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder)
+{
+	FLAC__ASSERT(0 != encoder);
+	FLAC__ASSERT(0 != encoder->private_);
+	FLAC__ASSERT(0 != encoder->protected_);
+	return encoder->protected_->limit_min_bitrate;
+}
+
 FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], uint32_t samples)
 {
-	uint32_t i, j = 0, channel;
-	const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
+	uint32_t i, j = 0, k = 0, channel;
+	const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize, bps = encoder->protected_->bits_per_sample;
+	const FLAC__int32 sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample);
+	const FLAC__int32 sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample);
 
 	FLAC__ASSERT(0 != encoder);
 	FLAC__ASSERT(0 != encoder->private_);
 	FLAC__ASSERT(0 != encoder->protected_);
-	FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
 
+	if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK)
+		return false;
+
 	do {
 		const uint32_t n = flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j);
 
@@ -2189,6 +2248,12 @@
 			append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, n);
 
 		for(channel = 0; channel < channels; channel++) {
+			for(i = encoder->private_->current_sample_number, k = j; i <= blocksize && k < samples; i++, k++) {
+				if(buffer[channel][k] < sample_min || buffer[channel][k] > sample_max){
+					encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
+					return false;
+				}
+			}
 			if (buffer[channel] == NULL) {
 				return false;
 			}
@@ -2198,10 +2263,16 @@
 		if(encoder->protected_->do_mid_side_stereo) {
 			FLAC__ASSERT(channels == 2);
 			/* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
-			for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
-				encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j];
-				encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
-			}
+			if(bps < 32)
+				for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
+					encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j];
+					encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
+				}
+			else
+				for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
+					encoder->private_->integer_signal_33bit_side[i] = (FLAC__int64)buffer[0][j] - (FLAC__int64)buffer[1][j];
+					encoder->private_->integer_signal_mid_side[0][i] = ((FLAC__int64)buffer[0][j] + (FLAC__int64)buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
+				}
 		}
 		else
 			j += n;
@@ -2212,7 +2283,7 @@
 		if(encoder->private_->current_sample_number > blocksize) {
 			FLAC__ASSERT(encoder->private_->current_sample_number == blocksize+OVERREAD_);
 			FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */
-			if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
+			if(!process_frame_(encoder, /*is_last_block=*/false))
 				return false;
 			/* move unprocessed overread samples to beginnings of arrays */
 			for(channel = 0; channel < channels; channel++)
@@ -2219,7 +2290,10 @@
 				encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize];
 			if(encoder->protected_->do_mid_side_stereo) {
 				encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
-				encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+				if(bps < 32)
+					encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+				else
+					encoder->private_->integer_signal_33bit_side[0] = encoder->private_->integer_signal_33bit_side[blocksize];
 			}
 			encoder->private_->current_sample_number = 1;
 		}
@@ -2231,14 +2305,17 @@
 FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], uint32_t samples)
 {
 	uint32_t i, j, k, channel;
-	FLAC__int32 x, mid, side;
-	const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
+	const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize, bps = encoder->protected_->bits_per_sample;
+	const FLAC__int32 sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample);
+	const FLAC__int32 sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample);
 
 	FLAC__ASSERT(0 != encoder);
 	FLAC__ASSERT(0 != encoder->private_);
 	FLAC__ASSERT(0 != encoder->protected_);
-	FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
 
+	if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK)
+		return false;
+
 	j = k = 0;
 	/*
 	 * we have several flavors of the same basic loop, optimized for
@@ -2254,19 +2331,26 @@
 
 			/* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
 			for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
-				encoder->private_->integer_signal[0][i] = mid = side = buffer[k++];
-				x = buffer[k++];
-				encoder->private_->integer_signal[1][i] = x;
-				mid += x;
-				side -= x;
-				mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */
-				encoder->private_->integer_signal_mid_side[1][i] = side;
-				encoder->private_->integer_signal_mid_side[0][i] = mid;
+				if(buffer[k]   < sample_min || buffer[k]   > sample_max ||
+				   buffer[k+1] < sample_min || buffer[k+1] > sample_max){
+					encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
+					return false;
+				}
+				encoder->private_->integer_signal[0][i] = buffer[k++];
+				encoder->private_->integer_signal[1][i] = buffer[k++];
+				if(bps < 32){
+					encoder->private_->integer_signal_mid_side[1][i] = encoder->private_->integer_signal[0][i] - encoder->private_->integer_signal[1][i];
+					encoder->private_->integer_signal_mid_side[0][i] = (encoder->private_->integer_signal[0][i] + encoder->private_->integer_signal[1][i]) >> 1;
+				}
+				else {
+					encoder->private_->integer_signal_33bit_side[i] = (FLAC__int64)encoder->private_->integer_signal[0][i] - (FLAC__int64)encoder->private_->integer_signal[1][i];
+					encoder->private_->integer_signal_mid_side[0][i] = ((FLAC__int64)encoder->private_->integer_signal[0][i] + (FLAC__int64)encoder->private_->integer_signal[1][i]) >> 1;
+				}
 			}
 			encoder->private_->current_sample_number = i;
 			/* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
 			if(i > blocksize) {
-				if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
+				if(!process_frame_(encoder, /*is_last_block=*/false))
 					return false;
 				/* move unprocessed overread samples to beginnings of arrays */
 				FLAC__ASSERT(i == blocksize+OVERREAD_);
@@ -2274,7 +2358,10 @@
 				encoder->private_->integer_signal[0][0] = encoder->private_->integer_signal[0][blocksize];
 				encoder->private_->integer_signal[1][0] = encoder->private_->integer_signal[1][blocksize];
 				encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
-				encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+				if(bps < 32)
+					encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+				else
+					encoder->private_->integer_signal_33bit_side[0] = encoder->private_->integer_signal_33bit_side[blocksize];
 				encoder->private_->current_sample_number = 1;
 			}
 		} while(j < samples);
@@ -2289,13 +2376,18 @@
 
 			/* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
 			for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
-				for(channel = 0; channel < channels; channel++)
+				for(channel = 0; channel < channels; channel++){
+					if(buffer[k] < sample_min || buffer[k] > sample_max){
+						encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
+						return false;
+					}
 					encoder->private_->integer_signal[channel][i] = buffer[k++];
+				}
 			}
 			encoder->private_->current_sample_number = i;
 			/* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
 			if(i > blocksize) {
-				if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
+				if(!process_frame_(encoder, /*is_last_block=*/false))
 					return false;
 				/* move unprocessed overread samples to beginnings of arrays */
 				FLAC__ASSERT(i == blocksize+OVERREAD_);
@@ -2347,10 +2439,16 @@
 	encoder->protected_->max_residual_partition_order = 0;
 	encoder->protected_->rice_parameter_search_dist = 0;
 	encoder->protected_->total_samples_estimate = 0;
+	encoder->protected_->limit_min_bitrate = false;
 	encoder->protected_->metadata = 0;
 	encoder->protected_->num_metadata_blocks = 0;
 
 	encoder->private_->seek_table = 0;
+	encoder->private_->disable_mmx = false;
+	encoder->private_->disable_sse2 = false;
+	encoder->private_->disable_ssse3 = false;
+	encoder->private_->disable_sse41 = false;
+	encoder->private_->disable_avx2 = false;
 	encoder->private_->disable_constant_subframes = false;
 	encoder->private_->disable_fixed_subframes = false;
 	encoder->private_->disable_verbatim_subframes = false;
@@ -2404,6 +2502,10 @@
 		}
 #endif
 	}
+	if(0 != encoder->private_->integer_signal_33bit_side_unaligned){
+		free(encoder->private_->integer_signal_33bit_side_unaligned);
+		encoder->private_->integer_signal_33bit_side_unaligned = 0;
+	}
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 	for(i = 0; i < encoder->protected_->num_apodizations; i++) {
 		if(0 != encoder->private_->window_unaligned[i]) {
@@ -2474,26 +2576,19 @@
 
 	for(i = 0; ok && i < encoder->protected_->channels; i++) {
 		ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]);
-		memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4);
-		encoder->private_->integer_signal[i] += 4;
-#ifndef FLAC__INTEGER_ONLY_LIBRARY
-#if 0 /* @@@ currently unused */
-		if(encoder->protected_->max_lpc_order > 0)
-			ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_unaligned[i], &encoder->private_->real_signal[i]);
-#endif
-#endif
+		if(ok) {
+			memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4);
+			encoder->private_->integer_signal[i] += 4;
+		}
 	}
 	for(i = 0; ok && i < 2; i++) {
 		ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]);
-		memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4);
-		encoder->private_->integer_signal_mid_side[i] += 4;
-#ifndef FLAC__INTEGER_ONLY_LIBRARY
-#if 0 /* @@@ currently unused */
-		if(encoder->protected_->max_lpc_order > 0)
-			ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_mid_side_unaligned[i], &encoder->private_->real_signal_mid_side[i]);
-#endif
-#endif
+		if(ok) {
+			memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4);
+			encoder->private_->integer_signal_mid_side[i] += 4;
+		}
 	}
+	ok = ok && FLAC__memory_alloc_aligned_int64_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_33bit_side_unaligned, &encoder->private_->integer_signal_33bit_side);
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 	if(ok && encoder->protected_->max_lpc_order > 0) {
 		for(i = 0; ok && i < encoder->protected_->num_apodizations; i++)
@@ -2506,11 +2601,32 @@
 			ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]);
 		}
 	}
+
+
+	for(channel = 0; ok && channel < encoder->protected_->channels; channel++) {
+		for(i = 0; ok && i < 2; i++) {
+			ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_workspace[channel][i], encoder->protected_->max_residual_partition_order);
+			ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_workspace[channel][i], encoder->protected_->max_residual_partition_order);
+		}
+	}
+
 	for(channel = 0; ok && channel < 2; channel++) {
 		for(i = 0; ok && i < 2; i++) {
 			ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->residual_workspace_mid_side[channel][i]);
 		}
 	}
+
+	for(channel = 0; ok && channel < 2; channel++) {
+		for(i = 0; ok && i < 2; i++) {
+			ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_workspace_mid_side[channel][i], encoder->protected_->max_residual_partition_order);
+		}
+	}
+
+	for(i = 0; ok && i < 2; i++) {
+		ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_extra[i], encoder->protected_->max_residual_partition_order);
+	}
+
+
 	/* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */
 	/*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */
 	ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums);
@@ -2570,6 +2686,9 @@
 				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_SUBDIVIDE_TUKEY:
+					FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p);
+					break;
 				case FLAC__APODIZATION_WELCH:
 					FLAC__window_welch(encoder->private_->window[i], new_blocksize);
 					break;
@@ -2612,7 +2731,8 @@
 		else {
 			if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder)
 			    || (!is_last_block
-				    && (FLAC__stream_encoder_get_verify_decoder_state(encoder) == FLAC__STREAM_DECODER_END_OF_STREAM))) {
+				    && (FLAC__stream_encoder_get_verify_decoder_state(encoder) == FLAC__STREAM_DECODER_END_OF_STREAM))
+			    || encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR /* Happens when error callback was used */) {
 				FLAC__bitwriter_release_buffer(encoder->private_->frame);
 				FLAC__bitwriter_clear(encoder->private_->frame);
 				if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
@@ -2738,7 +2858,7 @@
 {
 	FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
 	const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo;
-	const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
+	FLAC__uint64 samples = metadata->data.stream_info.total_samples;
 	const uint32_t min_framesize = metadata->data.stream_info.min_framesize;
 	const uint32_t max_framesize = metadata->data.stream_info.max_framesize;
 	const uint32_t bps = metadata->data.stream_info.bits_per_sample;
@@ -2795,6 +2915,8 @@
 				FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
 				- 4
 			) / 8;
+		if(samples > (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
+			samples = 0;
 
 		b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
 		b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
@@ -3079,7 +3201,7 @@
 }
 #endif
 
-FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block)
+FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block)
 {
 	FLAC__uint16 crc;
 	FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
@@ -3095,7 +3217,7 @@
 	/*
 	 * Process the frame header and subframes into the frame bitbuffer
 	 */
-	if(!process_subframes_(encoder, is_fractional_block)) {
+	if(!process_subframes_(encoder)) {
 		/* the above function sets the state for us in case of an error */
 		return false;
 	}
@@ -3138,22 +3260,18 @@
 	return true;
 }
 
-FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block)
+FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder)
 {
 	FLAC__FrameHeader frame_header;
 	uint32_t channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order;
-	FLAC__bool do_independent, do_mid_side;
+	FLAC__bool do_independent, do_mid_side, backup_disable_constant_subframes = encoder->private_->disable_constant_subframes, all_subframes_constant = true;
 
 	/*
 	 * Calculate the min,max Rice partition orders
 	 */
-	if(is_fractional_block) {
-		max_partition_order = 0;
-	}
-	else {
-		max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize);
-		max_partition_order = flac_min(max_partition_order, encoder->protected_->max_residual_partition_order);
-	}
+
+	max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize);
+	max_partition_order = flac_min(max_partition_order, encoder->protected_->max_residual_partition_order);
 	min_partition_order = flac_min(min_partition_order, max_partition_order);
 
 	/*
@@ -3209,7 +3327,12 @@
 	if(do_mid_side) {
 		FLAC__ASSERT(encoder->protected_->channels == 2);
 		for(channel = 0; channel < 2; channel++) {
-			uint32_t w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
+			uint32_t w;
+			if(encoder->protected_->bits_per_sample < 32 || channel == 0)
+				w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
+			else
+				w = get_wasted_bits_wide_(encoder->private_->integer_signal_33bit_side, encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
+
 			if (w > encoder->protected_->bits_per_sample) {
 				w = encoder->protected_->bits_per_sample;
 			}
@@ -3223,6 +3346,12 @@
 	 */
 	if(do_independent) {
 		for(channel = 0; channel < encoder->protected_->channels; channel++) {
+			if(encoder->protected_->limit_min_bitrate && all_subframes_constant && (channel + 1) == encoder->protected_->channels){
+				/* This frame contains only constant subframes at this point.
+				 * To prevent the frame from becoming too small, make sure
+				 * the last subframe isn't constant */
+				encoder->private_->disable_constant_subframes = true;
+			}
 			if(!
 				process_subframe_(
 					encoder,
@@ -3239,6 +3368,8 @@
 				)
 			)
 				return false;
+			if(encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]].type != FLAC__SUBFRAME_TYPE_CONSTANT)
+				all_subframes_constant = false;
 		}
 	}
 
@@ -3249,6 +3380,11 @@
 		FLAC__ASSERT(encoder->protected_->channels == 2);
 
 		for(channel = 0; channel < 2; channel++) {
+			void *integer_signal_;
+			if(encoder->private_->subframe_bps_mid_side[channel] <= 32)
+				integer_signal_ = encoder->private_->integer_signal_mid_side[channel];
+			else
+				integer_signal_ = encoder->private_->integer_signal_33bit_side;
 			if(!
 				process_subframe_(
 					encoder,
@@ -3256,7 +3392,7 @@
 					max_partition_order,
 					&frame_header,
 					encoder->private_->subframe_bps_mid_side[channel],
-					encoder->private_->integer_signal_mid_side[channel],
+					integer_signal_,
 					encoder->private_->subframe_workspace_ptr_mid_side[channel],
 					encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[channel],
 					encoder->private_->residual_workspace_mid_side[channel],
@@ -3300,7 +3436,11 @@
 
 			channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
 			min_bits = bits[channel_assignment];
-			for(ca = 1; ca <= 3; ca++) {
+
+			/* When doing loose mid-side stereo, ignore left-side
+			 * and right-side options */
+			ca = encoder->protected_->loose_mid_side_stereo ? 3 : 1;
+			for( ; ca <= 3; ca++) {
 				if(bits[ca] < min_bits) {
 					min_bits = bits[ca];
 					channel_assignment = (FLAC__ChannelAssignment)ca;
@@ -3384,10 +3524,36 @@
 	}
 
 	encoder->private_->last_channel_assignment = frame_header.channel_assignment;
+	encoder->private_->disable_constant_subframes = backup_disable_constant_subframes;
 
 	return true;
 }
 
+static inline void set_next_subdivide_tukey(FLAC__int32 parts, uint32_t * apodizations, uint32_t * current_depth, uint32_t * current_part){
+	// current_part is interleaved: even are partial, odd are punchout
+	if(*current_depth == 2){
+		// For depth 2, we only do partial, no punchout as that is almost redundant
+		if(*current_part == 0){
+			*current_part = 2;
+		}else{ /* *current_path == 2 */
+			*current_part = 0;
+			(*current_depth)++;
+		}
+	}else if((*current_part) < (2*(*current_depth)-1)){
+		(*current_part)++;
+	}else{ /* (*current_part) >= (2*(*current_depth)-1) */
+		*current_part = 0;
+		(*current_depth)++;
+	}
+
+	/* Now check if we are done with this SUBDIVIDE_TUKEY apodization */
+	if(*current_depth > (uint32_t) parts){
+		(*apodizations)++;
+		*current_depth = 1;
+		*current_part = 0;
+	}
+}
+
 FLAC__bool process_subframe_(
 	FLAC__StreamEncoder *encoder,
 	uint32_t min_partition_order,
@@ -3394,7 +3560,7 @@
 	uint32_t max_partition_order,
 	const FLAC__FrameHeader *frame_header,
 	uint32_t subframe_bps,
-	const FLAC__int32 integer_signal[],
+	const void *integer_signal,
 	FLAC__Subframe *subframe[2],
 	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
 	FLAC__int32 *residual[2],
@@ -3409,13 +3575,13 @@
 #endif
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 	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 and x86 intrinsic routines need all the space */
+	double 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 */
+	double autoc_root[FLAC__MAX_LPC_ORDER+1]; /* This is for subdivide_tukey apodization */
 	double lpc_error[FLAC__MAX_LPC_ORDER];
 	uint32_t min_lpc_order, max_lpc_order, lpc_order;
 	uint32_t min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision;
 #endif
 	uint32_t min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order;
-	uint32_t rice_parameter;
 	uint32_t _candidate_bits, _best_bits;
 	uint32_t _best_subframe;
 	/* only use RICE2 partitions if stream bps > 16 */
@@ -3426,16 +3592,33 @@
 	/* verbatim subframe is the baseline against which we measure other compressed subframes */
 	_best_subframe = 0;
 	if(encoder->private_->disable_verbatim_subframes && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER)
-		_best_bits = UINT_MAX;
+		_best_bits = UINT32_MAX;
 	else
 		_best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]);
+	*best_bits = _best_bits;
 
-	if(frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) {
+	if(frame_header->blocksize > FLAC__MAX_FIXED_ORDER) {
 		uint32_t signal_is_constant = false;
-		if(subframe_bps + 4 + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)|1) <= 32)
-			guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+		/* The next formula determines when to use a 64-bit accumulator
+		 * for the error of a fixed predictor, and when a 32-bit one. As
+		 * the error of a 4th order predictor for a given sample is the
+		 * sum of 17 sample values (1+4+6+4+1) and there are blocksize -
+		 * order error values to be summed, the maximum total error is
+		 * maximum_sample_value * (blocksize - order) * 17. As ilog2(x)
+		 * calculates floor(2log(x)), the result must be 31 or lower
+		 */
+		if(subframe_bps < 28){
+			if(subframe_bps + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)*17) < 32)
+				guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+			else
+				guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+		}
 		else
-			guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+			if(subframe_bps <= 32)
+				guess_fixed_order = FLAC__fixed_compute_best_predictor_limit_residual(((FLAC__int32 *)integer_signal),frame_header->blocksize, fixed_residual_bits_per_sample);
+			else
+				guess_fixed_order = FLAC__fixed_compute_best_predictor_limit_residual_33bit(((FLAC__int64 *)integer_signal),frame_header->blocksize, fixed_residual_bits_per_sample);
+
 		/* check for constant subframe */
 		if(
 			!encoder->private_->disable_constant_subframes &&
@@ -3448,15 +3631,31 @@
 			/* the above means it's possible all samples are the same value; now double-check it: */
 			uint32_t i;
 			signal_is_constant = true;
-			for(i = 1; i < frame_header->blocksize; i++) {
-				if(integer_signal[0] != integer_signal[i]) {
-					signal_is_constant = false;
-					break;
+			if(subframe_bps <= 32){
+				const FLAC__int32 *integer_signal_ = integer_signal;
+				for(i = 1; i < frame_header->blocksize; i++) {
+					if(integer_signal_[0] != integer_signal_[i]) {
+						signal_is_constant = false;
+						break;
+					}
 				}
 			}
+			else {
+				const FLAC__int64 *integer_signal_ = integer_signal;
+				for(i = 1; i < frame_header->blocksize; i++) {
+					if(integer_signal_[0] != integer_signal_[i]) {
+						signal_is_constant = false;
+						break;
+					}
+				}
+			}
 		}
 		if(signal_is_constant) {
-			_candidate_bits = evaluate_constant_subframe_(encoder, integer_signal[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
+			if(subframe_bps <= 32)
+				_candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int32 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
+			else
+				_candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int64 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
+
 			if(_candidate_bits < _best_bits) {
 				_best_subframe = !_best_subframe;
 				_best_bits = _candidate_bits;
@@ -3478,19 +3677,10 @@
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 					if(fixed_residual_bits_per_sample[fixed_order] >= (float)subframe_bps)
 						continue; /* don't even try */
-					rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (uint32_t)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0; /* 0.5 is for rounding */
 #else
 					if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps)
 						continue; /* don't even try */
-					rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (uint32_t)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */
 #endif
-					rice_parameter++; /* to account for the signed->uint32_t conversion during rice coding */
-					if(rice_parameter >= rice_parameter_limit) {
-#ifndef NDEBUG
-						fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1);
-#endif
-						rice_parameter = rice_parameter_limit - 1;
-					}
 					_candidate_bits =
 						evaluate_fixed_subframe_(
 							encoder,
@@ -3501,7 +3691,6 @@
 							frame_header->blocksize,
 							subframe_bps,
 							fixed_order,
-							rice_parameter,
 							rice_parameter_limit,
 							min_partition_order,
 							max_partition_order,
@@ -3525,13 +3714,55 @@
 				else
 					max_lpc_order = encoder->protected_->max_lpc_order;
 				if(max_lpc_order > 0) {
-					uint32_t a;
-					for (a = 0; a < encoder->protected_->num_apodizations; a++) {
-						FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
-						encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order+1, autoc);
+					uint32_t a, b = 1, c = 0;
+					for (a = 0; a < encoder->protected_->num_apodizations;) {
+						uint32_t max_lpc_order_this_apodization = max_lpc_order;
+						if(b == 1){
+							/* window full subblock */
+							if(subframe_bps <= 32)
+								FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
+							else
+								FLAC__lpc_window_data_wide(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
+							encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order_this_apodization+1, autoc);
+							if(encoder->protected_->apodizations[a].type == FLAC__APODIZATION_SUBDIVIDE_TUKEY){
+								for(uint32_t i = 0; i < max_lpc_order_this_apodization; i++)
+									autoc_root[i] = autoc[i];
+								b++;
+							}else{
+								a++;
+							}
+						}
+						else {
+							/* window part of subblock */
+							if(max_lpc_order_this_apodization >= frame_header->blocksize/b) {
+								max_lpc_order_this_apodization = frame_header->blocksize/b - 1;
+								if(frame_header->blocksize/b > 0)
+									max_lpc_order_this_apodization = frame_header->blocksize/b - 1;
+								else {
+									set_next_subdivide_tukey(encoder->protected_->apodizations[a].parameters.subdivide_tukey.parts, &a, &b, &c);
+									continue;
+								}
+							}
+							if(!(c % 2)){
+								/* on even c, evaluate the (c/2)th partial window of size blocksize/b  */
+								if(subframe_bps <= 32)
+									FLAC__lpc_window_data_partial(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize, frame_header->blocksize/b/2, (c/2*frame_header->blocksize)/b);
+								else
+									FLAC__lpc_window_data_partial(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize, frame_header->blocksize/b/2, (c/2*frame_header->blocksize)/b);
+								encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize/b, max_lpc_order_this_apodization+1, autoc);
+							}else{
+								/* on uneven c, evaluate the root window (over the whole block) minus the previous partial window
+								 * similar to tukey_punchout apodization but more efficient	*/
+								for(uint32_t i = 0; i < max_lpc_order_this_apodization; i++)
+									autoc[i] = autoc_root[i] - autoc[i];
+							}
+							/* Next function sets a, b and c appropriate for next iteration */
+							set_next_subdivide_tukey(encoder->protected_->apodizations[a].parameters.subdivide_tukey.parts, &a, &b, &c);
+						}
+
 						/* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */
 						if(autoc[0] != 0.0) {
-							FLAC__lpc_compute_lp_coefficients(autoc, &max_lpc_order, encoder->private_->lp_coeff, lpc_error);
+							FLAC__lpc_compute_lp_coefficients(autoc, &max_lpc_order_this_apodization, encoder->private_->lp_coeff, lpc_error);
 							if(encoder->protected_->do_exhaustive_model_search) {
 								min_lpc_order = 1;
 							}
@@ -3539,7 +3770,7 @@
 								const uint32_t guess_lpc_order =
 									FLAC__lpc_compute_best_order(
 										lpc_error,
-										max_lpc_order,
+										max_lpc_order_this_apodization,
 										frame_header->blocksize,
 										subframe_bps + (
 											encoder->protected_->do_qlp_coeff_prec_search?
@@ -3547,22 +3778,14 @@
 												encoder->protected_->qlp_coeff_precision
 										)
 									);
-								min_lpc_order = max_lpc_order = guess_lpc_order;
+								min_lpc_order = max_lpc_order_this_apodization = guess_lpc_order;
 							}
-							if(max_lpc_order >= frame_header->blocksize)
-								max_lpc_order = frame_header->blocksize - 1;
-							for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order; lpc_order++) {
+							if(max_lpc_order_this_apodization >= frame_header->blocksize)
+								max_lpc_order_this_apodization = frame_header->blocksize - 1;
+							for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order_this_apodization; lpc_order++) {
 								lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order);
 								if(lpc_residual_bits_per_sample >= (double)subframe_bps)
 									continue; /* don't even try */
-								rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (uint32_t)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */
-								rice_parameter++; /* to account for the signed->uint32_t conversion during rice coding */
-								if(rice_parameter >= rice_parameter_limit) {
-#ifndef NDEBUG
-									fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1);
-#endif
-									rice_parameter = rice_parameter_limit - 1;
-								}
 								if(encoder->protected_->do_qlp_coeff_prec_search) {
 									min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
 									/* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps(+1bps for side channel) streams */
@@ -3589,7 +3812,6 @@
 											subframe_bps,
 											lpc_order,
 											qlp_coeff_precision,
-											rice_parameter,
 											rice_parameter_limit,
 											min_partition_order,
 											max_partition_order,
@@ -3615,7 +3837,7 @@
 	}
 
 	/* under rare circumstances this can happen when all but lpc subframe types are disabled: */
-	if(_best_bits == UINT_MAX) {
+	if(_best_bits == UINT32_MAX) {
 		FLAC__ASSERT(_best_subframe == 0);
 		_best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]);
 	}
@@ -3699,7 +3921,7 @@
 
 uint32_t evaluate_constant_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal,
+	const FLAC__int64 signal,
 	uint32_t blocksize,
 	uint32_t subframe_bps,
 	FLAC__Subframe *subframe
@@ -3722,7 +3944,7 @@
 
 uint32_t evaluate_fixed_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal[],
+	const void *signal,
 	FLAC__int32 residual[],
 	FLAC__uint64 abs_residual_partition_sums[],
 	uint32_t raw_bits_per_partition[],
@@ -3729,7 +3951,6 @@
 	uint32_t blocksize,
 	uint32_t subframe_bps,
 	uint32_t order,
-	uint32_t rice_parameter,
 	uint32_t rice_parameter_limit,
 	uint32_t min_partition_order,
 	uint32_t max_partition_order,
@@ -3742,7 +3963,12 @@
 	uint32_t i, residual_bits, estimate;
 	const uint32_t residual_samples = blocksize - order;
 
-	FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual);
+	if((subframe_bps + order) <= 32)
+		FLAC__fixed_compute_residual(((FLAC__int32 *)signal)+order, residual_samples, order, residual);
+	else if(subframe_bps <= 32)
+		FLAC__fixed_compute_residual_wide(((FLAC__int32 *)signal)+order, residual_samples, order, residual);
+	else
+		FLAC__fixed_compute_residual_wide_33bit(((FLAC__int64 *)signal)+order, residual_samples, order, residual);
 
 	subframe->type = FLAC__SUBFRAME_TYPE_FIXED;
 
@@ -3758,7 +3984,6 @@
 			raw_bits_per_partition,
 			residual_samples,
 			order,
-			rice_parameter,
 			rice_parameter_limit,
 			min_partition_order,
 			max_partition_order,
@@ -3769,10 +3994,18 @@
 		);
 
 	subframe->data.fixed.order = order;
-	for(i = 0; i < order; i++)
-		subframe->data.fixed.warmup[i] = signal[i];
+	if(subframe_bps <= 32)
+		for(i = 0; i < order; i++)
+			subframe->data.fixed.warmup[i] = ((FLAC__int32 *)signal)[i];
+	else
+		for(i = 0; i < order; i++)
+			subframe->data.fixed.warmup[i] = ((FLAC__int64 *)signal)[i];
 
-	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps) + residual_bits;
+	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps);
+	if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow
+		estimate += residual_bits;
+	else
+		estimate = UINT32_MAX;
 
 #if SPOTCHECK_ESTIMATE
 	spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
@@ -3784,7 +4017,7 @@
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 uint32_t evaluate_lpc_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal[],
+	const void *signal,
 	FLAC__int32 residual[],
 	FLAC__uint64 abs_residual_partition_sums[],
 	uint32_t raw_bits_per_partition[],
@@ -3793,7 +4026,6 @@
 	uint32_t subframe_bps,
 	uint32_t order,
 	uint32_t qlp_coeff_precision,
-	uint32_t rice_parameter,
 	uint32_t rice_parameter_limit,
 	uint32_t min_partition_order,
 	uint32_t max_partition_order,
@@ -3819,13 +4051,23 @@
 	if(ret != 0)
 		return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
 
-	if(subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
-		if(subframe_bps <= 16 && qlp_coeff_precision <= 16)
-			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
+	if(FLAC__lpc_max_residual_bps(subframe_bps, qlp_coeff, order, quantization) > 32) {
+		if(subframe_bps <= 32){
+			if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual))
+				return 0;
+		}
 		else
-			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
+			if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(((FLAC__int64 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual))
+				return 0;
+	}
 	else
-		encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
+		if(FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) <= 32)
+			if(subframe_bps <= 16 && qlp_coeff_precision <= 16)
+				encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual);
+			else
+				encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual);
+		else
+			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual);
 
 	subframe->type = FLAC__SUBFRAME_TYPE_LPC;
 
@@ -3841,7 +4083,6 @@
 			raw_bits_per_partition,
 			residual_samples,
 			order,
-			rice_parameter,
 			rice_parameter_limit,
 			min_partition_order,
 			max_partition_order,
@@ -3855,11 +4096,20 @@
 	subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision;
 	subframe->data.lpc.quantization_level = quantization;
 	memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER);
-	for(i = 0; i < order; i++)
-		subframe->data.lpc.warmup[i] = signal[i];
+	if(subframe_bps <= 32)
+		for(i = 0; i < order; i++)
+			subframe->data.lpc.warmup[i] = ((FLAC__int32 *)signal)[i];
+	else
+		for(i = 0; i < order; i++)
+			subframe->data.lpc.warmup[i] = ((FLAC__int64 *)signal)[i];
 
-	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits;
 
+	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps));
+	if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow
+		estimate += residual_bits;
+	else
+		estimate = UINT32_MAX;
+
 #if SPOTCHECK_ESTIMATE
 	spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
 #endif
@@ -3870,7 +4120,7 @@
 
 uint32_t evaluate_verbatim_subframe_(
 	FLAC__StreamEncoder *encoder,
-	const FLAC__int32 signal[],
+	const void *signal,
 	uint32_t blocksize,
 	uint32_t subframe_bps,
 	FLAC__Subframe *subframe
@@ -3880,7 +4130,14 @@
 
 	subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM;
 
-	subframe->data.verbatim.data = signal;
+	if(subframe_bps <= 32){
+		subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32;
+		subframe->data.verbatim.data.int32 = signal;
+	}
+	else {
+		subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64;
+		subframe->data.verbatim.data.int64 = signal;
+	}
 
 	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps);
 
@@ -3900,7 +4157,6 @@
 	uint32_t raw_bits_per_partition[],
 	uint32_t residual_samples,
 	uint32_t predictor_order,
-	uint32_t rice_parameter,
 	uint32_t rice_parameter_limit,
 	uint32_t min_partition_order,
 	uint32_t max_partition_order,
@@ -3937,7 +4193,6 @@
 					raw_bits_per_partition+sum,
 					residual_samples,
 					predictor_order,
-					rice_parameter,
 					rice_parameter_limit,
 					rice_parameter_search_dist,
 					(uint32_t)partition_order,
@@ -3970,10 +4225,9 @@
 		uint32_t partition;
 
 		/* save best parameters and raw_bits */
-		FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, flac_max(6u, best_partition_order));
-		memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(uint32_t)*(1<<(best_partition_order)));
+		memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, (uint32_t)sizeof(uint32_t)*(1<<(best_partition_order)));
 		if(do_escape_coding)
-			memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(uint32_t)*(1<<(best_partition_order)));
+			memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, (uint32_t)sizeof(uint32_t)*(1<<(best_partition_order)));
 		/*
 		 * Now need to check if the type should be changed to
 		 * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the
@@ -4119,7 +4373,7 @@
 	;
 	for(i = 0; i < partition_samples; i++)
 		partition_bits += ( (FLAC__uint32)((residual[i]<<1)^(residual[i]>>31)) >> rice_parameter );
-	return (uint32_t)(flac_min(partition_bits,(uint32_t)(-1))); // To make sure the return value doesn't overflow
+	return (uint32_t)(flac_min(partition_bits,UINT32_MAX)); // To make sure the return value doesn't overflow
 }
 #else
 static inline uint32_t count_rice_bits_in_partition_(
@@ -4136,7 +4390,7 @@
 				(abs_residual_partition_sum >> (rice_parameter-1)) /* rice_parameter-1 because the real coder sign-folds instead of using a sign bit */
 				: (abs_residual_partition_sum << 1) /* can't shift by negative number, so reverse */
 		)
-		- (partition_samples >> 1),(uint32_t)(-1)));
+		- (partition_samples >> 1),UINT32_MAX));
 		/* -(partition_samples>>1) to subtract out extra contributions to the abs_residual_partition_sum.
 		 * The actual number of bits used is closer to the sum(for all i in the partition) of  abs(residual[i])>>(rice_parameter-1)
 		 * By using the abs_residual_partition sum, we also add in bits in the LSBs that would normally be shifted out.
@@ -4155,7 +4409,6 @@
 	const uint32_t raw_bits_per_partition[],
 	const uint32_t residual_samples,
 	const uint32_t predictor_order,
-	const uint32_t suggested_rice_parameter,
 	const uint32_t rice_parameter_limit,
 	const uint32_t rice_parameter_search_dist,
 	const uint32_t partition_order,
@@ -4168,6 +4421,10 @@
 	uint32_t best_partition_bits, best_rice_parameter = 0;
 	uint32_t bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN;
 	uint32_t *parameters, *raw_bits;
+	uint32_t partition, residual_sample;
+	uint32_t partition_samples;
+	const uint32_t partitions = 1u << partition_order;
+	FLAC__uint64 mean, k;
 #ifdef ENABLE_RICE_PARAMETER_SEARCH
 	uint32_t min_rice_parameter, max_rice_parameter;
 #else
@@ -4174,40 +4431,88 @@
 	(void)rice_parameter_search_dist;
 #endif
 
-	FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
 	FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
 
-	FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order));
 	parameters = partitioned_rice_contents->parameters;
 	raw_bits = partitioned_rice_contents->raw_bits;
 
-	if(partition_order == 0) {
-		best_partition_bits = (uint32_t)(-1);
+	for(partition = residual_sample = 0; partition < partitions; partition++) {
+		partition_samples = (residual_samples+predictor_order) >> partition_order;
+		if(partition == 0) {
+			if(partition_samples <= predictor_order)
+				return false;
+			else
+				partition_samples -= predictor_order;
+		}
+		mean = abs_residual_partition_sums[partition];
+		/* we are basically calculating the size in bits of the
+		 * average residual magnitude in the partition:
+		 *   rice_parameter = floor(log2(mean/partition_samples))
+		 * 'mean' is not a good name for the variable, it is
+		 * actually the sum of magnitudes of all residual values
+		 * in the partition, so the actual mean is
+		 * mean/partition_samples
+		 */
+#if 0 /* old simple code */
+		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) {
+#ifndef NDEBUG
+			fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);
+#endif
+			rice_parameter = rice_parameter_limit - 1;
+		}
+
+		best_partition_bits = UINT32_MAX;
 #ifdef ENABLE_RICE_PARAMETER_SEARCH
 		if(rice_parameter_search_dist) {
-			if(suggested_rice_parameter < rice_parameter_search_dist)
+			if(rice_parameter < rice_parameter_search_dist)
 				min_rice_parameter = 0;
 			else
-				min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist;
-			max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist;
+				min_rice_parameter = rice_parameter - rice_parameter_search_dist;
+			max_rice_parameter = rice_parameter + rice_parameter_search_dist;
 			if(max_rice_parameter >= rice_parameter_limit) {
 #ifndef NDEBUG
-				fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1);
+				fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1);
 #endif
 				max_rice_parameter = rice_parameter_limit - 1;
 			}
 		}
 		else
-			min_rice_parameter = max_rice_parameter = suggested_rice_parameter;
+			min_rice_parameter = max_rice_parameter = rice_parameter;
 
 		for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
-#else
-			rice_parameter = suggested_rice_parameter;
 #endif
 #ifdef EXACT_RICE_BITS_CALCULATION
-			partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, residual);
+			partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample);
 #else
-			partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, abs_residual_partition_sums[0]);
+			partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]);
 #endif
 			if(partition_bits < best_partition_bits) {
 				best_rice_parameter = rice_parameter;
@@ -4217,130 +4522,23 @@
 		}
 #endif
 		if(search_for_escapes) {
-			partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples;
-			if(partition_bits <= best_partition_bits) {
-				raw_bits[0] = raw_bits_per_partition[0];
+			partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples;
+			if(partition_bits <= best_partition_bits && raw_bits_per_partition[partition] < 32) {
+				raw_bits[partition] = raw_bits_per_partition[partition];
 				best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
 				best_partition_bits = partition_bits;
 			}
 			else
-				raw_bits[0] = 0;
+				raw_bits[partition] = 0;
 		}
-		parameters[0] = best_rice_parameter;
-		if(best_partition_bits < UINT_MAX - bits_) // To make sure _bits doesn't overflow
+		parameters[partition] = best_rice_parameter;
+		if(best_partition_bits < UINT32_MAX - bits_) // To make sure _bits doesn't overflow
 			bits_ += best_partition_bits;
 		else
-			bits_ = UINT_MAX;
+			bits_ = UINT32_MAX;
+		residual_sample += partition_samples;
 	}
-	else {
-		uint32_t partition, residual_sample;
-		uint32_t partition_samples;
-		FLAC__uint64 mean, k;
-		const uint32_t partitions = 1u << partition_order;
-		for(partition = residual_sample = 0; partition < partitions; partition++) {
-			partition_samples = (residual_samples+predictor_order) >> partition_order;
-			if(partition == 0) {
-				if(partition_samples <= predictor_order)
-					return false;
-				else
-					partition_samples -= predictor_order;
-			}
-			mean = abs_residual_partition_sums[partition];
-			/* we are basically calculating the size in bits of the
-			 * average residual magnitude in the partition:
-			 *   rice_parameter = floor(log2(mean/partition_samples))
-			 * 'mean' is not a good name for the variable, it is
-			 * actually the sum of magnitudes of all residual values
-			 * in the partition, so the actual mean is
-			 * mean/partition_samples
-			 */
-#if 0 /* old simple code */
-			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) {
-#ifndef NDEBUG
-				fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);
-#endif
-				rice_parameter = rice_parameter_limit - 1;
-			}
 
-			best_partition_bits = (uint32_t)(-1);
-#ifdef ENABLE_RICE_PARAMETER_SEARCH
-			if(rice_parameter_search_dist) {
-				if(rice_parameter < rice_parameter_search_dist)
-					min_rice_parameter = 0;
-				else
-					min_rice_parameter = rice_parameter - rice_parameter_search_dist;
-				max_rice_parameter = rice_parameter + rice_parameter_search_dist;
-				if(max_rice_parameter >= rice_parameter_limit) {
-#ifndef NDEBUG
-					fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1);
-#endif
-					max_rice_parameter = rice_parameter_limit - 1;
-				}
-			}
-			else
-				min_rice_parameter = max_rice_parameter = rice_parameter;
-
-			for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
-#endif
-#ifdef EXACT_RICE_BITS_CALCULATION
-				partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample);
-#else
-				partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]);
-#endif
-				if(partition_bits < best_partition_bits) {
-					best_rice_parameter = rice_parameter;
-					best_partition_bits = partition_bits;
-				}
-#ifdef ENABLE_RICE_PARAMETER_SEARCH
-			}
-#endif
-			if(search_for_escapes) {
-				partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples;
-				if(partition_bits <= best_partition_bits) {
-					raw_bits[partition] = raw_bits_per_partition[partition];
-					best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
-					best_partition_bits = partition_bits;
-				}
-				else
-					raw_bits[partition] = 0;
-			}
-			parameters[partition] = best_rice_parameter;
-			if(best_partition_bits < UINT_MAX - bits_) // To make sure _bits doesn't overflow
-				bits_ += best_partition_bits;
-			else
-				bits_ = UINT_MAX;
-			residual_sample += partition_samples;
-		}
-	}
-
 	*bits = bits_;
 	return true;
 }
@@ -4369,6 +4567,31 @@
 	return shift;
 }
 
+uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples)
+{
+	uint32_t i, shift;
+	FLAC__int64 x = 0;
+
+	for(i = 0; i < samples && !(x&1); i++)
+		x |= signal_wide[i];
+
+	if(x == 0) {
+		shift = 1;
+	}
+	else {
+		for(shift = 0; !(x&1); shift++)
+			x >>= 1;
+	}
+
+	if(shift > 0) {
+		for(i = 0; i < samples; i++)
+			 signal[i] = (FLAC__int32)(signal_wide[i] >> shift);
+	}
+
+	return shift;
+}
+
+
 void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], uint32_t input_offset, uint32_t channels, uint32_t wide_samples)
 {
 	uint32_t channel;
@@ -4438,6 +4661,11 @@
 	const uint32_t bytes_per_block = sizeof(FLAC__int32) * blocksize;
 
 	(void)decoder;
+
+	if(encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) {
+		/* This is set when verify_error_callback_ was called */
+		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+	}
 
 	for(channel = 0; channel < channels; channel++) {
 		if(0 != memcmp(buffer[channel], encoder->private_->verify.input_fifo.data[channel], bytes_per_block)) {
--- a/sys/src/cmd/audio/libFLAC/stream_encoder_framing.c
+++ b/sys/src/cmd/audio/libFLAC/stream_encoder_framing.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2000-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -96,9 +96,13 @@
 			FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN));
 			if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN))
 				return false;
-			FLAC__ASSERT(metadata->data.stream_info.total_samples < (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN));
-			if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
-				return false;
+			if(metadata->data.stream_info.total_samples >= (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)){
+				if(!FLAC__bitwriter_write_raw_uint64(bw, 0, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
+					return false;
+			}else{
+				if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
+					return false;
+			}
 			if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16))
 				return false;
 			break;
@@ -278,7 +282,7 @@
 		default:
 			if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0)
 				sample_rate_hint = u = 12;
-			else if(header->sample_rate % 10 == 0)
+			else if(header->sample_rate <= 655350 && header->sample_rate % 10 == 0)
 				sample_rate_hint = u = 14;
 			else if(header->sample_rate <= 0xffff)
 				sample_rate_hint = u = 13;
@@ -319,6 +323,7 @@
 		case 16: u = 4; break;
 		case 20: u = 5; break;
 		case 24: u = 6; break;
+		case 32: u = 7; break;
 		default: u = 0; break;
 	}
 	if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN))
@@ -371,7 +376,7 @@
 	ok =
 		FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) &&
 		(wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) &&
-		FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps)
+		FLAC__bitwriter_write_raw_int64(bw, subframe->value, subframe_bps)
 	;
 
 	return ok;
@@ -388,7 +393,7 @@
 			return false;
 
 	for(i = 0; i < subframe->order; i++)
-		if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
+		if(!FLAC__bitwriter_write_raw_int64(bw, subframe->warmup[i], subframe_bps))
 			return false;
 
 	if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method))
@@ -426,7 +431,7 @@
 			return false;
 
 	for(i = 0; i < subframe->order; i++)
-		if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
+		if(!FLAC__bitwriter_write_raw_int64(bw, subframe->warmup[i], subframe_bps))
 			return false;
 
 	if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
@@ -464,7 +469,6 @@
 FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, uint32_t samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw)
 {
 	uint32_t i;
-	const FLAC__int32 *signal = subframe->data;
 
 	if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
 		return false;
@@ -472,9 +476,24 @@
 		if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
 			return false;
 
-	for(i = 0; i < samples; i++)
-		if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps))
-			return false;
+	if(subframe->data_type == FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32) {
+		const FLAC__int32 *signal = subframe->data.int32;
+
+		FLAC__ASSERT(subframe_bps < 33);
+
+		for(i = 0; i < samples; i++)
+			if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps))
+				return false;
+	}
+	else {
+		const FLAC__int64 *signal = subframe->data.int64;
+
+		FLAC__ASSERT(subframe_bps == 33);
+
+		for(i = 0; i < samples; i++)
+			if(!FLAC__bitwriter_write_raw_int64(bw, (FLAC__int64)signal[i], subframe_bps))
+				return false;
+	}
 
 	return true;
 }
--- a/sys/src/cmd/audio/libFLAC/window.c
+++ b/sys/src/cmd/audio/libFLAC/window.c
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2006-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,9 +42,9 @@
 
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 
-#ifdef Plan9
-#define cosf cos
-#define fabsf fabs
+#if defined(_MSC_VER)
+// silence 25 MSVC warnings 'conversion from 'double' to 'float', possible loss of data'
+#pragma warning ( disable : 4244 )
 #endif
 
 void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
@@ -122,9 +122,15 @@
 	const double N2 = (double)N / 2.;
 	FLAC__int32 n;
 
-	for (n = 0; n <= N; n++) {
-		const double k = ((double)n - N2) / (stddev * N2);
-		window[n] = (FLAC__real)exp(-0.5f * k * k);
+	if(!(stddev > 0.0f && stddev <= 0.5f))
+		/* stddev is not between 0 and 0.5, might be NaN.
+		 * Default to 0.5 */
+		FLAC__window_gauss(window, L, 0.25f);
+	else {
+		for (n = 0; n <= N; n++) {
+			const double k = ((double)n - N2) / (stddev * N2);
+			window[n] = (FLAC__real)exp(-0.5f * k * k);
+		}
 	}
 }
 
@@ -196,6 +202,10 @@
 		FLAC__window_rectangle(window, L);
 	else if (p >= 1.0)
 		FLAC__window_hann(window, L);
+	else if (!(p > 0.0f && p < 1.0f))
+		/* p is not between 0 and 1, probably NaN.
+		 * Default to 0.5 */
+		FLAC__window_tukey(window, L, 0.5f);
 	else {
 		const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1;
 		FLAC__int32 n;
@@ -222,6 +232,10 @@
 		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 if (!(p > 0.0f && p < 1.0f))
+		/* p is not between 0 and 1, probably NaN.
+		 * Default to 0.5 */
+		FLAC__window_partial_tukey(window, L, 0.5f, start, end);
 	else {
 
 		Np = (FLAC__int32)(p / 2.0f * N);
@@ -249,6 +263,10 @@
 		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 if (!(p > 0.0f && p < 1.0f))
+		/* p is not between 0 and 1, probably NaN.
+		 * Default to 0.5 */
+		FLAC__window_punchout_tukey(window, L, 0.5f, start, end);
 	else {
 
 		Ns = (FLAC__int32)(p / 2.0f * start_n);
@@ -282,5 +300,9 @@
 		window[n] = (FLAC__real)(1.0f - k * k);
 	}
 }
+
+#if defined(_MSC_VER)
+#pragma warning ( default : 4244 )
+#endif
 
 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */