The "GR-PEACH_Audio_Playback_7InchLCD_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.
Dependencies: GR-PEACH_video R_BSP TLV320_RBSP USBHost_custom
Fork of GR-PEACH_Audio_Playback_Sample by
Note
For a sample program of without LCD Board, please refer to GR-PEACH_Audio_Playback_Sample.
Introduction
The "GR-PEACH_Audio_Playback_7InchLCD_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.
1. Overview of the Sample Code
1.1 Software Block Diagram
Figure 1.1 shows the software block diagram.
1.2 Pin Definitions
Table 1.1 shows the pins used in this sample code.
2. Sample Code Operating Environment
In order to operate this sample code, GR-PEACH, Audio Camera Shield and 7.1 inch LCD Shield must be needed. For details on Audio Camera Shield and 7.1 inch LCD Shield, please refer to the following links, respectively:
- Audio Camera Shield
https://developer.mbed.org/teams/Renesas/wiki/Audio_Camera-shield - 7.1 inch LCD Shield
https://developer.mbed.org/teams/Renesas/wiki/LCD-shield
In this section, it is described that how board is configured and to control audio playback via command line and touch screen.
2.1 Operating Environment
Figure 2.1 shows the overview of the operating environment for this sample code.
Figure 2.2 and 2.3 show how to configure GR-PEACH, Audio Camera Shield and 7.1 inch LCD shield when using USB0 and USB1, respectively.
Table 2.1 lists the overview of Graphical User Interface (GUI) of this sample code.
2.2 List of User Operations
Table 2.2 shows the relationship among Audio Playback, Command Line and Onboard Switch.
3. Function Outline
Table 3.1, 3.2 and 3.3 shows the overview of functions implemented in this sample code.
3.1 Playback Control
This sample program supports the operation "play", "pause", "stop", "play next song" and "play previous song".
3.2 Trick Play Control
In order to enable/disable Repeat Mode, user need to type "repeat" on command line or click the corresponding icon shown in Table 2.2. By derault, Repeat Mode is enabled. When Repeat Mode is enabled, the first song is played back after the playback of the last song is finished. Otherwise, the playback is shopped when finishing to play back the last song.
3.3 How to see Song Information
The information of the song being played back can be seen by typing playinfo on command line. Table 3.4 lists the items user can see on the terminal.
3.4 How to analyze the folder structure in USB stick
In this sample code, the folder structure in USB stick is analyzed in the breadth-first order. Table 3.5 shows how the files in USB stick are numbered.
4.Others
4.1 Serial Communication Setting
With respect to the default serial communication related setting on mbed, please refer to the follwing link:
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication
Please set up the terminal software you would like to use on your PC in consideration of the above. For example, 9600 should be specified for the baud rate on the terminal in order to control this sample via command line.
4.2 Necessary modification when using GCC ARM Embedded
If you would like to use GCC ARM Embedded, you must revise the following linker script incorporated in mbed OS 5 package as follows:
- Linker Script to be modified
$(PROJECT_ROOT)/mbed-os/targets/TARGET_RENESAS/TARGET_RZ_A1H/device/TOOLCHAIN_GCC_ARM/RZA1H.ld
Please note that $(PROJECT_ROOT) in the above denotes the root directory of this sample code
- Before Modification
RZA1H.ld
/* Linker script for mbed RZ_A1H */
/* Linker script to configure memory regions. */
MEMORY
{
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x02000000
BOOT_LOADER (rx) : ORIGIN = 0x18000000, LENGTH = 0x00004000
SFLASH (rx) : ORIGIN = 0x18004000, LENGTH = 0x07FFC000
L_TTB (rw) : ORIGIN = 0x20000000, LENGTH = 0x00004000
RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x00700000
RAM_NC (rwx) : ORIGIN = 0x20900000, LENGTH = 0x00100000
}
(snip)
- After Modification
RZA1H.ld
/* Linker script for mbed RZ_A1H */
/* Linker script to configure memory regions. */
MEMORY
{
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x02000000
BOOT_LOADER (rx) : ORIGIN = 0x18000000, LENGTH = 0x00004000
SFLASH (rx) : ORIGIN = 0x18004000, LENGTH = 0x07FFC000
L_TTB (rw) : ORIGIN = 0x20000000, LENGTH = 0x00004000
RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x00180000
RAM_NC (rwx) : ORIGIN = 0x20200000, LENGTH = 0x00680000
}
(snip)
flac/src/libFLAC/lpc.c@0:ee40da884cfc, 2015-10-16 (annotated)
- Committer:
- dkato
- Date:
- Fri Oct 16 04:28:07 2015 +0000
- Revision:
- 0:ee40da884cfc
first commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| dkato | 0:ee40da884cfc | 1 | /* libFLAC - Free Lossless Audio Codec library |
| dkato | 0:ee40da884cfc | 2 | * Copyright (C) 2000-2009 Josh Coalson |
| dkato | 0:ee40da884cfc | 3 | * Copyright (C) 2011-2014 Xiph.Org Foundation |
| dkato | 0:ee40da884cfc | 4 | * |
| dkato | 0:ee40da884cfc | 5 | * Redistribution and use in source and binary forms, with or without |
| dkato | 0:ee40da884cfc | 6 | * modification, are permitted provided that the following conditions |
| dkato | 0:ee40da884cfc | 7 | * are met: |
| dkato | 0:ee40da884cfc | 8 | * |
| dkato | 0:ee40da884cfc | 9 | * - Redistributions of source code must retain the above copyright |
| dkato | 0:ee40da884cfc | 10 | * notice, this list of conditions and the following disclaimer. |
| dkato | 0:ee40da884cfc | 11 | * |
| dkato | 0:ee40da884cfc | 12 | * - Redistributions in binary form must reproduce the above copyright |
| dkato | 0:ee40da884cfc | 13 | * notice, this list of conditions and the following disclaimer in the |
| dkato | 0:ee40da884cfc | 14 | * documentation and/or other materials provided with the distribution. |
| dkato | 0:ee40da884cfc | 15 | * |
| dkato | 0:ee40da884cfc | 16 | * - Neither the name of the Xiph.org Foundation nor the names of its |
| dkato | 0:ee40da884cfc | 17 | * contributors may be used to endorse or promote products derived from |
| dkato | 0:ee40da884cfc | 18 | * this software without specific prior written permission. |
| dkato | 0:ee40da884cfc | 19 | * |
| dkato | 0:ee40da884cfc | 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| dkato | 0:ee40da884cfc | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| dkato | 0:ee40da884cfc | 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| dkato | 0:ee40da884cfc | 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
| dkato | 0:ee40da884cfc | 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| dkato | 0:ee40da884cfc | 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| dkato | 0:ee40da884cfc | 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| dkato | 0:ee40da884cfc | 27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| dkato | 0:ee40da884cfc | 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| dkato | 0:ee40da884cfc | 29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| dkato | 0:ee40da884cfc | 30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| dkato | 0:ee40da884cfc | 31 | */ |
| dkato | 0:ee40da884cfc | 32 | |
| dkato | 0:ee40da884cfc | 33 | #ifdef HAVE_CONFIG_H |
| dkato | 0:ee40da884cfc | 34 | # include <config.h> |
| dkato | 0:ee40da884cfc | 35 | #endif |
| dkato | 0:ee40da884cfc | 36 | |
| dkato | 0:ee40da884cfc | 37 | #include <math.h> |
| dkato | 0:ee40da884cfc | 38 | |
| dkato | 0:ee40da884cfc | 39 | #include "FLAC/assert.h" |
| dkato | 0:ee40da884cfc | 40 | #include "FLAC/format.h" |
| dkato | 0:ee40da884cfc | 41 | #include "share/compat.h" |
| dkato | 0:ee40da884cfc | 42 | #include "private/bitmath.h" |
| dkato | 0:ee40da884cfc | 43 | #include "private/lpc.h" |
| dkato | 0:ee40da884cfc | 44 | #include "private/macros.h" |
| dkato | 0:ee40da884cfc | 45 | #if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE |
| dkato | 0:ee40da884cfc | 46 | #include <stdio.h> |
| dkato | 0:ee40da884cfc | 47 | #endif |
| dkato | 0:ee40da884cfc | 48 | |
| dkato | 0:ee40da884cfc | 49 | /* OPT: #undef'ing this may improve the speed on some architectures */ |
| dkato | 0:ee40da884cfc | 50 | #define FLAC__LPC_UNROLLED_FILTER_LOOPS |
| dkato | 0:ee40da884cfc | 51 | |
| dkato | 0:ee40da884cfc | 52 | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
| dkato | 0:ee40da884cfc | 53 | |
| dkato | 0:ee40da884cfc | 54 | #if !defined(HAVE_LROUND) |
| dkato | 0:ee40da884cfc | 55 | #if defined(_MSC_VER) |
| dkato | 0:ee40da884cfc | 56 | #include <float.h> |
| dkato | 0:ee40da884cfc | 57 | #define copysign _copysign |
| dkato | 0:ee40da884cfc | 58 | #elif defined(__GNUC__) |
| dkato | 0:ee40da884cfc | 59 | #define copysign __builtin_copysign |
| dkato | 0:ee40da884cfc | 60 | #endif |
| dkato | 0:ee40da884cfc | 61 | static inline long int lround(double x) { |
| dkato | 0:ee40da884cfc | 62 | return (long)(x + copysign (0.5, x)); |
| dkato | 0:ee40da884cfc | 63 | } |
| dkato | 0:ee40da884cfc | 64 | /* If this fails, we are in the presence of a mid 90's compiler, move along... */ |
| dkato | 0:ee40da884cfc | 65 | #endif |
| dkato | 0:ee40da884cfc | 66 | |
| dkato | 0:ee40da884cfc | 67 | void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) |
| dkato | 0:ee40da884cfc | 68 | { |
| dkato | 0:ee40da884cfc | 69 | unsigned i; |
| dkato | 0:ee40da884cfc | 70 | for(i = 0; i < data_len; i++) |
| dkato | 0:ee40da884cfc | 71 | out[i] = in[i] * window[i]; |
| dkato | 0:ee40da884cfc | 72 | } |
| dkato | 0:ee40da884cfc | 73 | |
| dkato | 0:ee40da884cfc | 74 | void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) |
| dkato | 0:ee40da884cfc | 75 | { |
| dkato | 0:ee40da884cfc | 76 | /* a readable, but slower, version */ |
| dkato | 0:ee40da884cfc | 77 | #if 0 |
| dkato | 0:ee40da884cfc | 78 | FLAC__real d; |
| dkato | 0:ee40da884cfc | 79 | unsigned i; |
| dkato | 0:ee40da884cfc | 80 | |
| dkato | 0:ee40da884cfc | 81 | FLAC__ASSERT(lag > 0); |
| dkato | 0:ee40da884cfc | 82 | FLAC__ASSERT(lag <= data_len); |
| dkato | 0:ee40da884cfc | 83 | |
| dkato | 0:ee40da884cfc | 84 | /* |
| dkato | 0:ee40da884cfc | 85 | * Technically we should subtract the mean first like so: |
| dkato | 0:ee40da884cfc | 86 | * for(i = 0; i < data_len; i++) |
| dkato | 0:ee40da884cfc | 87 | * data[i] -= mean; |
| dkato | 0:ee40da884cfc | 88 | * but it appears not to make enough of a difference to matter, and |
| dkato | 0:ee40da884cfc | 89 | * most signals are already closely centered around zero |
| dkato | 0:ee40da884cfc | 90 | */ |
| dkato | 0:ee40da884cfc | 91 | while(lag--) { |
| dkato | 0:ee40da884cfc | 92 | for(i = lag, d = 0.0; i < data_len; i++) |
| dkato | 0:ee40da884cfc | 93 | d += data[i] * data[i - lag]; |
| dkato | 0:ee40da884cfc | 94 | autoc[lag] = d; |
| dkato | 0:ee40da884cfc | 95 | } |
| dkato | 0:ee40da884cfc | 96 | #endif |
| dkato | 0:ee40da884cfc | 97 | |
| dkato | 0:ee40da884cfc | 98 | /* |
| dkato | 0:ee40da884cfc | 99 | * this version tends to run faster because of better data locality |
| dkato | 0:ee40da884cfc | 100 | * ('data_len' is usually much larger than 'lag') |
| dkato | 0:ee40da884cfc | 101 | */ |
| dkato | 0:ee40da884cfc | 102 | FLAC__real d; |
| dkato | 0:ee40da884cfc | 103 | unsigned sample, coeff; |
| dkato | 0:ee40da884cfc | 104 | const unsigned limit = data_len - lag; |
| dkato | 0:ee40da884cfc | 105 | |
| dkato | 0:ee40da884cfc | 106 | FLAC__ASSERT(lag > 0); |
| dkato | 0:ee40da884cfc | 107 | FLAC__ASSERT(lag <= data_len); |
| dkato | 0:ee40da884cfc | 108 | |
| dkato | 0:ee40da884cfc | 109 | for(coeff = 0; coeff < lag; coeff++) |
| dkato | 0:ee40da884cfc | 110 | autoc[coeff] = 0.0; |
| dkato | 0:ee40da884cfc | 111 | for(sample = 0; sample <= limit; sample++) { |
| dkato | 0:ee40da884cfc | 112 | d = data[sample]; |
| dkato | 0:ee40da884cfc | 113 | for(coeff = 0; coeff < lag; coeff++) |
| dkato | 0:ee40da884cfc | 114 | autoc[coeff] += d * data[sample+coeff]; |
| dkato | 0:ee40da884cfc | 115 | } |
| dkato | 0:ee40da884cfc | 116 | for(; sample < data_len; sample++) { |
| dkato | 0:ee40da884cfc | 117 | d = data[sample]; |
| dkato | 0:ee40da884cfc | 118 | for(coeff = 0; coeff < data_len - sample; coeff++) |
| dkato | 0:ee40da884cfc | 119 | autoc[coeff] += d * data[sample+coeff]; |
| dkato | 0:ee40da884cfc | 120 | } |
| dkato | 0:ee40da884cfc | 121 | } |
| dkato | 0:ee40da884cfc | 122 | |
| dkato | 0:ee40da884cfc | 123 | void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[]) |
| dkato | 0:ee40da884cfc | 124 | { |
| dkato | 0:ee40da884cfc | 125 | unsigned i, j; |
| dkato | 0:ee40da884cfc | 126 | FLAC__double r, err, lpc[FLAC__MAX_LPC_ORDER]; |
| dkato | 0:ee40da884cfc | 127 | |
| dkato | 0:ee40da884cfc | 128 | FLAC__ASSERT(0 != max_order); |
| dkato | 0:ee40da884cfc | 129 | FLAC__ASSERT(0 < *max_order); |
| dkato | 0:ee40da884cfc | 130 | FLAC__ASSERT(*max_order <= FLAC__MAX_LPC_ORDER); |
| dkato | 0:ee40da884cfc | 131 | FLAC__ASSERT(autoc[0] != 0.0); |
| dkato | 0:ee40da884cfc | 132 | |
| dkato | 0:ee40da884cfc | 133 | err = autoc[0]; |
| dkato | 0:ee40da884cfc | 134 | |
| dkato | 0:ee40da884cfc | 135 | for(i = 0; i < *max_order; i++) { |
| dkato | 0:ee40da884cfc | 136 | /* Sum up this iteration's reflection coefficient. */ |
| dkato | 0:ee40da884cfc | 137 | r = -autoc[i+1]; |
| dkato | 0:ee40da884cfc | 138 | for(j = 0; j < i; j++) |
| dkato | 0:ee40da884cfc | 139 | r -= lpc[j] * autoc[i-j]; |
| dkato | 0:ee40da884cfc | 140 | r /= err; |
| dkato | 0:ee40da884cfc | 141 | |
| dkato | 0:ee40da884cfc | 142 | /* Update LPC coefficients and total error. */ |
| dkato | 0:ee40da884cfc | 143 | lpc[i]=r; |
| dkato | 0:ee40da884cfc | 144 | for(j = 0; j < (i>>1); j++) { |
| dkato | 0:ee40da884cfc | 145 | FLAC__double tmp = lpc[j]; |
| dkato | 0:ee40da884cfc | 146 | lpc[j] += r * lpc[i-1-j]; |
| dkato | 0:ee40da884cfc | 147 | lpc[i-1-j] += r * tmp; |
| dkato | 0:ee40da884cfc | 148 | } |
| dkato | 0:ee40da884cfc | 149 | if(i & 1) |
| dkato | 0:ee40da884cfc | 150 | lpc[j] += lpc[j] * r; |
| dkato | 0:ee40da884cfc | 151 | |
| dkato | 0:ee40da884cfc | 152 | err *= (1.0 - r * r); |
| dkato | 0:ee40da884cfc | 153 | |
| dkato | 0:ee40da884cfc | 154 | /* save this order */ |
| dkato | 0:ee40da884cfc | 155 | for(j = 0; j <= i; j++) |
| dkato | 0:ee40da884cfc | 156 | lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */ |
| dkato | 0:ee40da884cfc | 157 | error[i] = err; |
| dkato | 0:ee40da884cfc | 158 | |
| dkato | 0:ee40da884cfc | 159 | /* see SF bug https://sourceforge.net/p/flac/bugs/234/ */ |
| dkato | 0:ee40da884cfc | 160 | if(err == 0.0) { |
| dkato | 0:ee40da884cfc | 161 | *max_order = i+1; |
| dkato | 0:ee40da884cfc | 162 | return; |
| dkato | 0:ee40da884cfc | 163 | } |
| dkato | 0:ee40da884cfc | 164 | } |
| dkato | 0:ee40da884cfc | 165 | } |
| dkato | 0:ee40da884cfc | 166 | |
| dkato | 0:ee40da884cfc | 167 | int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift) |
| dkato | 0:ee40da884cfc | 168 | { |
| dkato | 0:ee40da884cfc | 169 | unsigned i; |
| dkato | 0:ee40da884cfc | 170 | FLAC__double cmax; |
| dkato | 0:ee40da884cfc | 171 | FLAC__int32 qmax, qmin; |
| dkato | 0:ee40da884cfc | 172 | |
| dkato | 0:ee40da884cfc | 173 | FLAC__ASSERT(precision > 0); |
| dkato | 0:ee40da884cfc | 174 | FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION); |
| dkato | 0:ee40da884cfc | 175 | |
| dkato | 0:ee40da884cfc | 176 | /* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */ |
| dkato | 0:ee40da884cfc | 177 | precision--; |
| dkato | 0:ee40da884cfc | 178 | qmax = 1 << precision; |
| dkato | 0:ee40da884cfc | 179 | qmin = -qmax; |
| dkato | 0:ee40da884cfc | 180 | qmax--; |
| dkato | 0:ee40da884cfc | 181 | |
| dkato | 0:ee40da884cfc | 182 | /* calc cmax = max( |lp_coeff[i]| ) */ |
| dkato | 0:ee40da884cfc | 183 | cmax = 0.0; |
| dkato | 0:ee40da884cfc | 184 | for(i = 0; i < order; i++) { |
| dkato | 0:ee40da884cfc | 185 | const FLAC__double d = fabs(lp_coeff[i]); |
| dkato | 0:ee40da884cfc | 186 | if(d > cmax) |
| dkato | 0:ee40da884cfc | 187 | cmax = d; |
| dkato | 0:ee40da884cfc | 188 | } |
| dkato | 0:ee40da884cfc | 189 | |
| dkato | 0:ee40da884cfc | 190 | if(cmax <= 0.0) { |
| dkato | 0:ee40da884cfc | 191 | /* => coefficients are all 0, which means our constant-detect didn't work */ |
| dkato | 0:ee40da884cfc | 192 | return 2; |
| dkato | 0:ee40da884cfc | 193 | } |
| dkato | 0:ee40da884cfc | 194 | else { |
| dkato | 0:ee40da884cfc | 195 | const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN-1)) - 1; |
| dkato | 0:ee40da884cfc | 196 | const int min_shiftlimit = -max_shiftlimit - 1; |
| dkato | 0:ee40da884cfc | 197 | int log2cmax; |
| dkato | 0:ee40da884cfc | 198 | |
| dkato | 0:ee40da884cfc | 199 | (void)frexp(cmax, &log2cmax); |
| dkato | 0:ee40da884cfc | 200 | log2cmax--; |
| dkato | 0:ee40da884cfc | 201 | *shift = (int)precision - log2cmax - 1; |
| dkato | 0:ee40da884cfc | 202 | |
| dkato | 0:ee40da884cfc | 203 | if(*shift > max_shiftlimit) |
| dkato | 0:ee40da884cfc | 204 | *shift = max_shiftlimit; |
| dkato | 0:ee40da884cfc | 205 | else if(*shift < min_shiftlimit) |
| dkato | 0:ee40da884cfc | 206 | return 1; |
| dkato | 0:ee40da884cfc | 207 | } |
| dkato | 0:ee40da884cfc | 208 | |
| dkato | 0:ee40da884cfc | 209 | if(*shift >= 0) { |
| dkato | 0:ee40da884cfc | 210 | FLAC__double error = 0.0; |
| dkato | 0:ee40da884cfc | 211 | FLAC__int32 q; |
| dkato | 0:ee40da884cfc | 212 | for(i = 0; i < order; i++) { |
| dkato | 0:ee40da884cfc | 213 | error += lp_coeff[i] * (1 << *shift); |
| dkato | 0:ee40da884cfc | 214 | q = lround(error); |
| dkato | 0:ee40da884cfc | 215 | |
| dkato | 0:ee40da884cfc | 216 | #ifdef FLAC__OVERFLOW_DETECT |
| dkato | 0:ee40da884cfc | 217 | if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ |
| dkato | 0:ee40da884cfc | 218 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); |
| dkato | 0:ee40da884cfc | 219 | else if(q < qmin) |
| dkato | 0:ee40da884cfc | 220 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmin,*shift,cmax,precision+1,i,lp_coeff[i]); |
| dkato | 0:ee40da884cfc | 221 | #endif |
| dkato | 0:ee40da884cfc | 222 | if(q > qmax) |
| dkato | 0:ee40da884cfc | 223 | q = qmax; |
| dkato | 0:ee40da884cfc | 224 | else if(q < qmin) |
| dkato | 0:ee40da884cfc | 225 | q = qmin; |
| dkato | 0:ee40da884cfc | 226 | error -= q; |
| dkato | 0:ee40da884cfc | 227 | qlp_coeff[i] = q; |
| dkato | 0:ee40da884cfc | 228 | } |
| dkato | 0:ee40da884cfc | 229 | } |
| dkato | 0:ee40da884cfc | 230 | /* negative shift is very rare but due to design flaw, negative shift is |
| dkato | 0:ee40da884cfc | 231 | * a NOP in the decoder, so it must be handled specially by scaling down |
| dkato | 0:ee40da884cfc | 232 | * coeffs |
| dkato | 0:ee40da884cfc | 233 | */ |
| dkato | 0:ee40da884cfc | 234 | else { |
| dkato | 0:ee40da884cfc | 235 | const int nshift = -(*shift); |
| dkato | 0:ee40da884cfc | 236 | FLAC__double error = 0.0; |
| dkato | 0:ee40da884cfc | 237 | FLAC__int32 q; |
| dkato | 0:ee40da884cfc | 238 | #ifdef DEBUG |
| dkato | 0:ee40da884cfc | 239 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: negative shift=%d order=%u cmax=%f\n", *shift, order, cmax); |
| dkato | 0:ee40da884cfc | 240 | #endif |
| dkato | 0:ee40da884cfc | 241 | for(i = 0; i < order; i++) { |
| dkato | 0:ee40da884cfc | 242 | error += lp_coeff[i] / (1 << nshift); |
| dkato | 0:ee40da884cfc | 243 | q = lround(error); |
| dkato | 0:ee40da884cfc | 244 | #ifdef FLAC__OVERFLOW_DETECT |
| dkato | 0:ee40da884cfc | 245 | if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ |
| dkato | 0:ee40da884cfc | 246 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); |
| dkato | 0:ee40da884cfc | 247 | else if(q < qmin) |
| dkato | 0:ee40da884cfc | 248 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmin,*shift,cmax,precision+1,i,lp_coeff[i]); |
| dkato | 0:ee40da884cfc | 249 | #endif |
| dkato | 0:ee40da884cfc | 250 | if(q > qmax) |
| dkato | 0:ee40da884cfc | 251 | q = qmax; |
| dkato | 0:ee40da884cfc | 252 | else if(q < qmin) |
| dkato | 0:ee40da884cfc | 253 | q = qmin; |
| dkato | 0:ee40da884cfc | 254 | error -= q; |
| dkato | 0:ee40da884cfc | 255 | qlp_coeff[i] = q; |
| dkato | 0:ee40da884cfc | 256 | } |
| dkato | 0:ee40da884cfc | 257 | *shift = 0; |
| dkato | 0:ee40da884cfc | 258 | } |
| dkato | 0:ee40da884cfc | 259 | |
| dkato | 0:ee40da884cfc | 260 | return 0; |
| dkato | 0:ee40da884cfc | 261 | } |
| dkato | 0:ee40da884cfc | 262 | |
| dkato | 0:ee40da884cfc | 263 | #if defined(_MSC_VER) |
| dkato | 0:ee40da884cfc | 264 | // silence MSVC warnings about __restrict modifier |
| dkato | 0:ee40da884cfc | 265 | #pragma warning ( disable : 4028 ) |
| dkato | 0:ee40da884cfc | 266 | #endif |
| dkato | 0:ee40da884cfc | 267 | |
| dkato | 0:ee40da884cfc | 268 | void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual) |
| dkato | 0:ee40da884cfc | 269 | #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) |
| dkato | 0:ee40da884cfc | 270 | { |
| dkato | 0:ee40da884cfc | 271 | FLAC__int64 sumo; |
| dkato | 0:ee40da884cfc | 272 | unsigned i, j; |
| dkato | 0:ee40da884cfc | 273 | FLAC__int32 sum; |
| dkato | 0:ee40da884cfc | 274 | const FLAC__int32 *history; |
| dkato | 0:ee40da884cfc | 275 | |
| dkato | 0:ee40da884cfc | 276 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE |
| dkato | 0:ee40da884cfc | 277 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); |
| dkato | 0:ee40da884cfc | 278 | for(i=0;i<order;i++) |
| dkato | 0:ee40da884cfc | 279 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); |
| dkato | 0:ee40da884cfc | 280 | fprintf(stderr,"\n"); |
| dkato | 0:ee40da884cfc | 281 | #endif |
| dkato | 0:ee40da884cfc | 282 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 283 | |
| dkato | 0:ee40da884cfc | 284 | for(i = 0; i < data_len; i++) { |
| dkato | 0:ee40da884cfc | 285 | sumo = 0; |
| dkato | 0:ee40da884cfc | 286 | sum = 0; |
| dkato | 0:ee40da884cfc | 287 | history = data; |
| dkato | 0:ee40da884cfc | 288 | for(j = 0; j < order; j++) { |
| dkato | 0:ee40da884cfc | 289 | sum += qlp_coeff[j] * (*(--history)); |
| dkato | 0:ee40da884cfc | 290 | sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); |
| dkato | 0:ee40da884cfc | 291 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); |
| dkato | 0:ee40da884cfc | 292 | } |
| dkato | 0:ee40da884cfc | 293 | *(residual++) = *(data++) - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 294 | } |
| dkato | 0:ee40da884cfc | 295 | |
| dkato | 0:ee40da884cfc | 296 | /* Here's a slower but clearer version: |
| dkato | 0:ee40da884cfc | 297 | for(i = 0; i < data_len; i++) { |
| dkato | 0:ee40da884cfc | 298 | sum = 0; |
| dkato | 0:ee40da884cfc | 299 | for(j = 0; j < order; j++) |
| dkato | 0:ee40da884cfc | 300 | sum += qlp_coeff[j] * data[i-j-1]; |
| dkato | 0:ee40da884cfc | 301 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 302 | } |
| dkato | 0:ee40da884cfc | 303 | */ |
| dkato | 0:ee40da884cfc | 304 | } |
| dkato | 0:ee40da884cfc | 305 | #else /* fully unrolled version for normal use */ |
| dkato | 0:ee40da884cfc | 306 | { |
| dkato | 0:ee40da884cfc | 307 | int i; |
| dkato | 0:ee40da884cfc | 308 | FLAC__int32 sum; |
| dkato | 0:ee40da884cfc | 309 | |
| dkato | 0:ee40da884cfc | 310 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 311 | FLAC__ASSERT(order <= 32); |
| dkato | 0:ee40da884cfc | 312 | |
| dkato | 0:ee40da884cfc | 313 | /* |
| dkato | 0:ee40da884cfc | 314 | * We do unique versions up to 12th order since that's the subset limit. |
| dkato | 0:ee40da884cfc | 315 | * Also they are roughly ordered to match frequency of occurrence to |
| dkato | 0:ee40da884cfc | 316 | * minimize branching. |
| dkato | 0:ee40da884cfc | 317 | */ |
| dkato | 0:ee40da884cfc | 318 | if(order <= 12) { |
| dkato | 0:ee40da884cfc | 319 | if(order > 8) { |
| dkato | 0:ee40da884cfc | 320 | if(order > 10) { |
| dkato | 0:ee40da884cfc | 321 | if(order == 12) { |
| dkato | 0:ee40da884cfc | 322 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 323 | sum = 0; |
| dkato | 0:ee40da884cfc | 324 | sum += qlp_coeff[11] * data[i-12]; |
| dkato | 0:ee40da884cfc | 325 | sum += qlp_coeff[10] * data[i-11]; |
| dkato | 0:ee40da884cfc | 326 | sum += qlp_coeff[9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 327 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 328 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 329 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 330 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 331 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 332 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 333 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 334 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 335 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 336 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 337 | } |
| dkato | 0:ee40da884cfc | 338 | } |
| dkato | 0:ee40da884cfc | 339 | else { /* order == 11 */ |
| dkato | 0:ee40da884cfc | 340 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 341 | sum = 0; |
| dkato | 0:ee40da884cfc | 342 | sum += qlp_coeff[10] * data[i-11]; |
| dkato | 0:ee40da884cfc | 343 | sum += qlp_coeff[9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 344 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 345 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 346 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 347 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 348 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 349 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 350 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 351 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 352 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 353 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 354 | } |
| dkato | 0:ee40da884cfc | 355 | } |
| dkato | 0:ee40da884cfc | 356 | } |
| dkato | 0:ee40da884cfc | 357 | else { |
| dkato | 0:ee40da884cfc | 358 | if(order == 10) { |
| dkato | 0:ee40da884cfc | 359 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 360 | sum = 0; |
| dkato | 0:ee40da884cfc | 361 | sum += qlp_coeff[9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 362 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 363 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 364 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 365 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 366 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 367 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 368 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 369 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 370 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 371 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 372 | } |
| dkato | 0:ee40da884cfc | 373 | } |
| dkato | 0:ee40da884cfc | 374 | else { /* order == 9 */ |
| dkato | 0:ee40da884cfc | 375 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 376 | sum = 0; |
| dkato | 0:ee40da884cfc | 377 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 378 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 379 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 380 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 381 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 382 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 383 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 384 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 385 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 386 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 387 | } |
| dkato | 0:ee40da884cfc | 388 | } |
| dkato | 0:ee40da884cfc | 389 | } |
| dkato | 0:ee40da884cfc | 390 | } |
| dkato | 0:ee40da884cfc | 391 | else if(order > 4) { |
| dkato | 0:ee40da884cfc | 392 | if(order > 6) { |
| dkato | 0:ee40da884cfc | 393 | if(order == 8) { |
| dkato | 0:ee40da884cfc | 394 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 395 | sum = 0; |
| dkato | 0:ee40da884cfc | 396 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 397 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 398 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 399 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 400 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 401 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 402 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 403 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 404 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 405 | } |
| dkato | 0:ee40da884cfc | 406 | } |
| dkato | 0:ee40da884cfc | 407 | else { /* order == 7 */ |
| dkato | 0:ee40da884cfc | 408 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 409 | sum = 0; |
| dkato | 0:ee40da884cfc | 410 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 411 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 412 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 413 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 414 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 415 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 416 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 417 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 418 | } |
| dkato | 0:ee40da884cfc | 419 | } |
| dkato | 0:ee40da884cfc | 420 | } |
| dkato | 0:ee40da884cfc | 421 | else { |
| dkato | 0:ee40da884cfc | 422 | if(order == 6) { |
| dkato | 0:ee40da884cfc | 423 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 424 | sum = 0; |
| dkato | 0:ee40da884cfc | 425 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 426 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 427 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 428 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 429 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 430 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 431 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 432 | } |
| dkato | 0:ee40da884cfc | 433 | } |
| dkato | 0:ee40da884cfc | 434 | else { /* order == 5 */ |
| dkato | 0:ee40da884cfc | 435 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 436 | sum = 0; |
| dkato | 0:ee40da884cfc | 437 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 438 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 439 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 440 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 441 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 442 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 443 | } |
| dkato | 0:ee40da884cfc | 444 | } |
| dkato | 0:ee40da884cfc | 445 | } |
| dkato | 0:ee40da884cfc | 446 | } |
| dkato | 0:ee40da884cfc | 447 | else { |
| dkato | 0:ee40da884cfc | 448 | if(order > 2) { |
| dkato | 0:ee40da884cfc | 449 | if(order == 4) { |
| dkato | 0:ee40da884cfc | 450 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 451 | sum = 0; |
| dkato | 0:ee40da884cfc | 452 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 453 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 454 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 455 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 456 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 457 | } |
| dkato | 0:ee40da884cfc | 458 | } |
| dkato | 0:ee40da884cfc | 459 | else { /* order == 3 */ |
| dkato | 0:ee40da884cfc | 460 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 461 | sum = 0; |
| dkato | 0:ee40da884cfc | 462 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 463 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 464 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 465 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 466 | } |
| dkato | 0:ee40da884cfc | 467 | } |
| dkato | 0:ee40da884cfc | 468 | } |
| dkato | 0:ee40da884cfc | 469 | else { |
| dkato | 0:ee40da884cfc | 470 | if(order == 2) { |
| dkato | 0:ee40da884cfc | 471 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 472 | sum = 0; |
| dkato | 0:ee40da884cfc | 473 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 474 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 475 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 476 | } |
| dkato | 0:ee40da884cfc | 477 | } |
| dkato | 0:ee40da884cfc | 478 | else { /* order == 1 */ |
| dkato | 0:ee40da884cfc | 479 | for(i = 0; i < (int)data_len; i++) |
| dkato | 0:ee40da884cfc | 480 | residual[i] = data[i] - ((qlp_coeff[0] * data[i-1]) >> lp_quantization); |
| dkato | 0:ee40da884cfc | 481 | } |
| dkato | 0:ee40da884cfc | 482 | } |
| dkato | 0:ee40da884cfc | 483 | } |
| dkato | 0:ee40da884cfc | 484 | } |
| dkato | 0:ee40da884cfc | 485 | else { /* order > 12 */ |
| dkato | 0:ee40da884cfc | 486 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 487 | sum = 0; |
| dkato | 0:ee40da884cfc | 488 | switch(order) { |
| dkato | 0:ee40da884cfc | 489 | case 32: sum += qlp_coeff[31] * data[i-32]; |
| dkato | 0:ee40da884cfc | 490 | case 31: sum += qlp_coeff[30] * data[i-31]; |
| dkato | 0:ee40da884cfc | 491 | case 30: sum += qlp_coeff[29] * data[i-30]; |
| dkato | 0:ee40da884cfc | 492 | case 29: sum += qlp_coeff[28] * data[i-29]; |
| dkato | 0:ee40da884cfc | 493 | case 28: sum += qlp_coeff[27] * data[i-28]; |
| dkato | 0:ee40da884cfc | 494 | case 27: sum += qlp_coeff[26] * data[i-27]; |
| dkato | 0:ee40da884cfc | 495 | case 26: sum += qlp_coeff[25] * data[i-26]; |
| dkato | 0:ee40da884cfc | 496 | case 25: sum += qlp_coeff[24] * data[i-25]; |
| dkato | 0:ee40da884cfc | 497 | case 24: sum += qlp_coeff[23] * data[i-24]; |
| dkato | 0:ee40da884cfc | 498 | case 23: sum += qlp_coeff[22] * data[i-23]; |
| dkato | 0:ee40da884cfc | 499 | case 22: sum += qlp_coeff[21] * data[i-22]; |
| dkato | 0:ee40da884cfc | 500 | case 21: sum += qlp_coeff[20] * data[i-21]; |
| dkato | 0:ee40da884cfc | 501 | case 20: sum += qlp_coeff[19] * data[i-20]; |
| dkato | 0:ee40da884cfc | 502 | case 19: sum += qlp_coeff[18] * data[i-19]; |
| dkato | 0:ee40da884cfc | 503 | case 18: sum += qlp_coeff[17] * data[i-18]; |
| dkato | 0:ee40da884cfc | 504 | case 17: sum += qlp_coeff[16] * data[i-17]; |
| dkato | 0:ee40da884cfc | 505 | case 16: sum += qlp_coeff[15] * data[i-16]; |
| dkato | 0:ee40da884cfc | 506 | case 15: sum += qlp_coeff[14] * data[i-15]; |
| dkato | 0:ee40da884cfc | 507 | case 14: sum += qlp_coeff[13] * data[i-14]; |
| dkato | 0:ee40da884cfc | 508 | case 13: sum += qlp_coeff[12] * data[i-13]; |
| dkato | 0:ee40da884cfc | 509 | sum += qlp_coeff[11] * data[i-12]; |
| dkato | 0:ee40da884cfc | 510 | sum += qlp_coeff[10] * data[i-11]; |
| dkato | 0:ee40da884cfc | 511 | sum += qlp_coeff[ 9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 512 | sum += qlp_coeff[ 8] * data[i- 9]; |
| dkato | 0:ee40da884cfc | 513 | sum += qlp_coeff[ 7] * data[i- 8]; |
| dkato | 0:ee40da884cfc | 514 | sum += qlp_coeff[ 6] * data[i- 7]; |
| dkato | 0:ee40da884cfc | 515 | sum += qlp_coeff[ 5] * data[i- 6]; |
| dkato | 0:ee40da884cfc | 516 | sum += qlp_coeff[ 4] * data[i- 5]; |
| dkato | 0:ee40da884cfc | 517 | sum += qlp_coeff[ 3] * data[i- 4]; |
| dkato | 0:ee40da884cfc | 518 | sum += qlp_coeff[ 2] * data[i- 3]; |
| dkato | 0:ee40da884cfc | 519 | sum += qlp_coeff[ 1] * data[i- 2]; |
| dkato | 0:ee40da884cfc | 520 | sum += qlp_coeff[ 0] * data[i- 1]; |
| dkato | 0:ee40da884cfc | 521 | } |
| dkato | 0:ee40da884cfc | 522 | residual[i] = data[i] - (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 523 | } |
| dkato | 0:ee40da884cfc | 524 | } |
| dkato | 0:ee40da884cfc | 525 | } |
| dkato | 0:ee40da884cfc | 526 | #endif |
| dkato | 0:ee40da884cfc | 527 | |
| dkato | 0:ee40da884cfc | 528 | void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual) |
| dkato | 0:ee40da884cfc | 529 | #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) |
| dkato | 0:ee40da884cfc | 530 | { |
| dkato | 0:ee40da884cfc | 531 | unsigned i, j; |
| dkato | 0:ee40da884cfc | 532 | FLAC__int64 sum; |
| dkato | 0:ee40da884cfc | 533 | const FLAC__int32 *history; |
| dkato | 0:ee40da884cfc | 534 | |
| dkato | 0:ee40da884cfc | 535 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE |
| dkato | 0:ee40da884cfc | 536 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); |
| dkato | 0:ee40da884cfc | 537 | for(i=0;i<order;i++) |
| dkato | 0:ee40da884cfc | 538 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); |
| dkato | 0:ee40da884cfc | 539 | fprintf(stderr,"\n"); |
| dkato | 0:ee40da884cfc | 540 | #endif |
| dkato | 0:ee40da884cfc | 541 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 542 | |
| dkato | 0:ee40da884cfc | 543 | for(i = 0; i < data_len; i++) { |
| dkato | 0:ee40da884cfc | 544 | sum = 0; |
| dkato | 0:ee40da884cfc | 545 | history = data; |
| dkato | 0:ee40da884cfc | 546 | for(j = 0; j < order; j++) |
| dkato | 0:ee40da884cfc | 547 | sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); |
| dkato | 0:ee40da884cfc | 548 | if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { |
| dkato | 0:ee40da884cfc | 549 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); |
| dkato | 0:ee40da884cfc | 550 | break; |
| dkato | 0:ee40da884cfc | 551 | } |
| dkato | 0:ee40da884cfc | 552 | if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { |
| dkato | 0:ee40da884cfc | 553 | 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))); |
| dkato | 0:ee40da884cfc | 554 | break; |
| dkato | 0:ee40da884cfc | 555 | } |
| dkato | 0:ee40da884cfc | 556 | *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 557 | } |
| dkato | 0:ee40da884cfc | 558 | } |
| dkato | 0:ee40da884cfc | 559 | #else /* fully unrolled version for normal use */ |
| dkato | 0:ee40da884cfc | 560 | { |
| dkato | 0:ee40da884cfc | 561 | int i; |
| dkato | 0:ee40da884cfc | 562 | FLAC__int64 sum; |
| dkato | 0:ee40da884cfc | 563 | |
| dkato | 0:ee40da884cfc | 564 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 565 | FLAC__ASSERT(order <= 32); |
| dkato | 0:ee40da884cfc | 566 | |
| dkato | 0:ee40da884cfc | 567 | /* |
| dkato | 0:ee40da884cfc | 568 | * We do unique versions up to 12th order since that's the subset limit. |
| dkato | 0:ee40da884cfc | 569 | * Also they are roughly ordered to match frequency of occurrence to |
| dkato | 0:ee40da884cfc | 570 | * minimize branching. |
| dkato | 0:ee40da884cfc | 571 | */ |
| dkato | 0:ee40da884cfc | 572 | if(order <= 12) { |
| dkato | 0:ee40da884cfc | 573 | if(order > 8) { |
| dkato | 0:ee40da884cfc | 574 | if(order > 10) { |
| dkato | 0:ee40da884cfc | 575 | if(order == 12) { |
| dkato | 0:ee40da884cfc | 576 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 577 | sum = 0; |
| dkato | 0:ee40da884cfc | 578 | sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; |
| dkato | 0:ee40da884cfc | 579 | sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; |
| dkato | 0:ee40da884cfc | 580 | sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 581 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 582 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 583 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 584 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 585 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 586 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 587 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 588 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 589 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 590 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 591 | } |
| dkato | 0:ee40da884cfc | 592 | } |
| dkato | 0:ee40da884cfc | 593 | else { /* order == 11 */ |
| dkato | 0:ee40da884cfc | 594 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 595 | sum = 0; |
| dkato | 0:ee40da884cfc | 596 | sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; |
| dkato | 0:ee40da884cfc | 597 | sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 598 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 599 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 600 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 601 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 602 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 603 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 604 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 605 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 606 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 607 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 608 | } |
| dkato | 0:ee40da884cfc | 609 | } |
| dkato | 0:ee40da884cfc | 610 | } |
| dkato | 0:ee40da884cfc | 611 | else { |
| dkato | 0:ee40da884cfc | 612 | if(order == 10) { |
| dkato | 0:ee40da884cfc | 613 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 614 | sum = 0; |
| dkato | 0:ee40da884cfc | 615 | sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 616 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 617 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 618 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 619 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 620 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 621 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 622 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 623 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 624 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 625 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 626 | } |
| dkato | 0:ee40da884cfc | 627 | } |
| dkato | 0:ee40da884cfc | 628 | else { /* order == 9 */ |
| dkato | 0:ee40da884cfc | 629 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 630 | sum = 0; |
| dkato | 0:ee40da884cfc | 631 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 632 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 633 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 634 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 635 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 636 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 637 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 638 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 639 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 640 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 641 | } |
| dkato | 0:ee40da884cfc | 642 | } |
| dkato | 0:ee40da884cfc | 643 | } |
| dkato | 0:ee40da884cfc | 644 | } |
| dkato | 0:ee40da884cfc | 645 | else if(order > 4) { |
| dkato | 0:ee40da884cfc | 646 | if(order > 6) { |
| dkato | 0:ee40da884cfc | 647 | if(order == 8) { |
| dkato | 0:ee40da884cfc | 648 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 649 | sum = 0; |
| dkato | 0:ee40da884cfc | 650 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 651 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 652 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 653 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 654 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 655 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 656 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 657 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 658 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 659 | } |
| dkato | 0:ee40da884cfc | 660 | } |
| dkato | 0:ee40da884cfc | 661 | else { /* order == 7 */ |
| dkato | 0:ee40da884cfc | 662 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 663 | sum = 0; |
| dkato | 0:ee40da884cfc | 664 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 665 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 666 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 667 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 668 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 669 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 670 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 671 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 672 | } |
| dkato | 0:ee40da884cfc | 673 | } |
| dkato | 0:ee40da884cfc | 674 | } |
| dkato | 0:ee40da884cfc | 675 | else { |
| dkato | 0:ee40da884cfc | 676 | if(order == 6) { |
| dkato | 0:ee40da884cfc | 677 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 678 | sum = 0; |
| dkato | 0:ee40da884cfc | 679 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 680 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 681 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 682 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 683 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 684 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 685 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 686 | } |
| dkato | 0:ee40da884cfc | 687 | } |
| dkato | 0:ee40da884cfc | 688 | else { /* order == 5 */ |
| dkato | 0:ee40da884cfc | 689 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 690 | sum = 0; |
| dkato | 0:ee40da884cfc | 691 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 692 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 693 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 694 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 695 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 696 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 697 | } |
| dkato | 0:ee40da884cfc | 698 | } |
| dkato | 0:ee40da884cfc | 699 | } |
| dkato | 0:ee40da884cfc | 700 | } |
| dkato | 0:ee40da884cfc | 701 | else { |
| dkato | 0:ee40da884cfc | 702 | if(order > 2) { |
| dkato | 0:ee40da884cfc | 703 | if(order == 4) { |
| dkato | 0:ee40da884cfc | 704 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 705 | sum = 0; |
| dkato | 0:ee40da884cfc | 706 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 707 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 708 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 709 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 710 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 711 | } |
| dkato | 0:ee40da884cfc | 712 | } |
| dkato | 0:ee40da884cfc | 713 | else { /* order == 3 */ |
| dkato | 0:ee40da884cfc | 714 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 715 | sum = 0; |
| dkato | 0:ee40da884cfc | 716 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 717 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 718 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 719 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 720 | } |
| dkato | 0:ee40da884cfc | 721 | } |
| dkato | 0:ee40da884cfc | 722 | } |
| dkato | 0:ee40da884cfc | 723 | else { |
| dkato | 0:ee40da884cfc | 724 | if(order == 2) { |
| dkato | 0:ee40da884cfc | 725 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 726 | sum = 0; |
| dkato | 0:ee40da884cfc | 727 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 728 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 729 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 730 | } |
| dkato | 0:ee40da884cfc | 731 | } |
| dkato | 0:ee40da884cfc | 732 | else { /* order == 1 */ |
| dkato | 0:ee40da884cfc | 733 | for(i = 0; i < (int)data_len; i++) |
| dkato | 0:ee40da884cfc | 734 | residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); |
| dkato | 0:ee40da884cfc | 735 | } |
| dkato | 0:ee40da884cfc | 736 | } |
| dkato | 0:ee40da884cfc | 737 | } |
| dkato | 0:ee40da884cfc | 738 | } |
| dkato | 0:ee40da884cfc | 739 | else { /* order > 12 */ |
| dkato | 0:ee40da884cfc | 740 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 741 | sum = 0; |
| dkato | 0:ee40da884cfc | 742 | switch(order) { |
| dkato | 0:ee40da884cfc | 743 | case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; |
| dkato | 0:ee40da884cfc | 744 | case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; |
| dkato | 0:ee40da884cfc | 745 | case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; |
| dkato | 0:ee40da884cfc | 746 | case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; |
| dkato | 0:ee40da884cfc | 747 | case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; |
| dkato | 0:ee40da884cfc | 748 | case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; |
| dkato | 0:ee40da884cfc | 749 | case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; |
| dkato | 0:ee40da884cfc | 750 | case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; |
| dkato | 0:ee40da884cfc | 751 | case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; |
| dkato | 0:ee40da884cfc | 752 | case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; |
| dkato | 0:ee40da884cfc | 753 | case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; |
| dkato | 0:ee40da884cfc | 754 | case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; |
| dkato | 0:ee40da884cfc | 755 | case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; |
| dkato | 0:ee40da884cfc | 756 | case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; |
| dkato | 0:ee40da884cfc | 757 | case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; |
| dkato | 0:ee40da884cfc | 758 | case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; |
| dkato | 0:ee40da884cfc | 759 | case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; |
| dkato | 0:ee40da884cfc | 760 | case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; |
| dkato | 0:ee40da884cfc | 761 | case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; |
| dkato | 0:ee40da884cfc | 762 | case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; |
| dkato | 0:ee40da884cfc | 763 | sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; |
| dkato | 0:ee40da884cfc | 764 | sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; |
| dkato | 0:ee40da884cfc | 765 | sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 766 | sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; |
| dkato | 0:ee40da884cfc | 767 | sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; |
| dkato | 0:ee40da884cfc | 768 | sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; |
| dkato | 0:ee40da884cfc | 769 | sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; |
| dkato | 0:ee40da884cfc | 770 | sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; |
| dkato | 0:ee40da884cfc | 771 | sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; |
| dkato | 0:ee40da884cfc | 772 | sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; |
| dkato | 0:ee40da884cfc | 773 | sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; |
| dkato | 0:ee40da884cfc | 774 | sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; |
| dkato | 0:ee40da884cfc | 775 | } |
| dkato | 0:ee40da884cfc | 776 | residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 777 | } |
| dkato | 0:ee40da884cfc | 778 | } |
| dkato | 0:ee40da884cfc | 779 | } |
| dkato | 0:ee40da884cfc | 780 | #endif |
| dkato | 0:ee40da884cfc | 781 | |
| dkato | 0:ee40da884cfc | 782 | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ |
| dkato | 0:ee40da884cfc | 783 | |
| dkato | 0:ee40da884cfc | 784 | void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data) |
| dkato | 0:ee40da884cfc | 785 | #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) |
| dkato | 0:ee40da884cfc | 786 | { |
| dkato | 0:ee40da884cfc | 787 | FLAC__int64 sumo; |
| dkato | 0:ee40da884cfc | 788 | unsigned i, j; |
| dkato | 0:ee40da884cfc | 789 | FLAC__int32 sum; |
| dkato | 0:ee40da884cfc | 790 | const FLAC__int32 *r = residual, *history; |
| dkato | 0:ee40da884cfc | 791 | |
| dkato | 0:ee40da884cfc | 792 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE |
| dkato | 0:ee40da884cfc | 793 | fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); |
| dkato | 0:ee40da884cfc | 794 | for(i=0;i<order;i++) |
| dkato | 0:ee40da884cfc | 795 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); |
| dkato | 0:ee40da884cfc | 796 | fprintf(stderr,"\n"); |
| dkato | 0:ee40da884cfc | 797 | #endif |
| dkato | 0:ee40da884cfc | 798 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 799 | |
| dkato | 0:ee40da884cfc | 800 | for(i = 0; i < data_len; i++) { |
| dkato | 0:ee40da884cfc | 801 | sumo = 0; |
| dkato | 0:ee40da884cfc | 802 | sum = 0; |
| dkato | 0:ee40da884cfc | 803 | history = data; |
| dkato | 0:ee40da884cfc | 804 | for(j = 0; j < order; j++) { |
| dkato | 0:ee40da884cfc | 805 | sum += qlp_coeff[j] * (*(--history)); |
| dkato | 0:ee40da884cfc | 806 | sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); |
| dkato | 0:ee40da884cfc | 807 | if(sumo > 2147483647ll || sumo < -2147483648ll) |
| dkato | 0:ee40da884cfc | 808 | 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); |
| dkato | 0:ee40da884cfc | 809 | } |
| dkato | 0:ee40da884cfc | 810 | *(data++) = *(r++) + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 811 | } |
| dkato | 0:ee40da884cfc | 812 | |
| dkato | 0:ee40da884cfc | 813 | /* Here's a slower but clearer version: |
| dkato | 0:ee40da884cfc | 814 | for(i = 0; i < data_len; i++) { |
| dkato | 0:ee40da884cfc | 815 | sum = 0; |
| dkato | 0:ee40da884cfc | 816 | for(j = 0; j < order; j++) |
| dkato | 0:ee40da884cfc | 817 | sum += qlp_coeff[j] * data[i-j-1]; |
| dkato | 0:ee40da884cfc | 818 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 819 | } |
| dkato | 0:ee40da884cfc | 820 | */ |
| dkato | 0:ee40da884cfc | 821 | } |
| dkato | 0:ee40da884cfc | 822 | #else /* fully unrolled version for normal use */ |
| dkato | 0:ee40da884cfc | 823 | { |
| dkato | 0:ee40da884cfc | 824 | int i; |
| dkato | 0:ee40da884cfc | 825 | FLAC__int32 sum; |
| dkato | 0:ee40da884cfc | 826 | |
| dkato | 0:ee40da884cfc | 827 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 828 | FLAC__ASSERT(order <= 32); |
| dkato | 0:ee40da884cfc | 829 | |
| dkato | 0:ee40da884cfc | 830 | /* |
| dkato | 0:ee40da884cfc | 831 | * We do unique versions up to 12th order since that's the subset limit. |
| dkato | 0:ee40da884cfc | 832 | * Also they are roughly ordered to match frequency of occurrence to |
| dkato | 0:ee40da884cfc | 833 | * minimize branching. |
| dkato | 0:ee40da884cfc | 834 | */ |
| dkato | 0:ee40da884cfc | 835 | if(order <= 12) { |
| dkato | 0:ee40da884cfc | 836 | if(order > 8) { |
| dkato | 0:ee40da884cfc | 837 | if(order > 10) { |
| dkato | 0:ee40da884cfc | 838 | if(order == 12) { |
| dkato | 0:ee40da884cfc | 839 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 840 | sum = 0; |
| dkato | 0:ee40da884cfc | 841 | sum += qlp_coeff[11] * data[i-12]; |
| dkato | 0:ee40da884cfc | 842 | sum += qlp_coeff[10] * data[i-11]; |
| dkato | 0:ee40da884cfc | 843 | sum += qlp_coeff[9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 844 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 845 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 846 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 847 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 848 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 849 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 850 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 851 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 852 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 853 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 854 | } |
| dkato | 0:ee40da884cfc | 855 | } |
| dkato | 0:ee40da884cfc | 856 | else { /* order == 11 */ |
| dkato | 0:ee40da884cfc | 857 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 858 | sum = 0; |
| dkato | 0:ee40da884cfc | 859 | sum += qlp_coeff[10] * data[i-11]; |
| dkato | 0:ee40da884cfc | 860 | sum += qlp_coeff[9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 861 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 862 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 863 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 864 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 865 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 866 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 867 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 868 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 869 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 870 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 871 | } |
| dkato | 0:ee40da884cfc | 872 | } |
| dkato | 0:ee40da884cfc | 873 | } |
| dkato | 0:ee40da884cfc | 874 | else { |
| dkato | 0:ee40da884cfc | 875 | if(order == 10) { |
| dkato | 0:ee40da884cfc | 876 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 877 | sum = 0; |
| dkato | 0:ee40da884cfc | 878 | sum += qlp_coeff[9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 879 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 880 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 881 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 882 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 883 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 884 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 885 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 886 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 887 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 888 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 889 | } |
| dkato | 0:ee40da884cfc | 890 | } |
| dkato | 0:ee40da884cfc | 891 | else { /* order == 9 */ |
| dkato | 0:ee40da884cfc | 892 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 893 | sum = 0; |
| dkato | 0:ee40da884cfc | 894 | sum += qlp_coeff[8] * data[i-9]; |
| dkato | 0:ee40da884cfc | 895 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 896 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 897 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 898 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 899 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 900 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 901 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 902 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 903 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 904 | } |
| dkato | 0:ee40da884cfc | 905 | } |
| dkato | 0:ee40da884cfc | 906 | } |
| dkato | 0:ee40da884cfc | 907 | } |
| dkato | 0:ee40da884cfc | 908 | else if(order > 4) { |
| dkato | 0:ee40da884cfc | 909 | if(order > 6) { |
| dkato | 0:ee40da884cfc | 910 | if(order == 8) { |
| dkato | 0:ee40da884cfc | 911 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 912 | sum = 0; |
| dkato | 0:ee40da884cfc | 913 | sum += qlp_coeff[7] * data[i-8]; |
| dkato | 0:ee40da884cfc | 914 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 915 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 916 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 917 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 918 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 919 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 920 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 921 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 922 | } |
| dkato | 0:ee40da884cfc | 923 | } |
| dkato | 0:ee40da884cfc | 924 | else { /* order == 7 */ |
| dkato | 0:ee40da884cfc | 925 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 926 | sum = 0; |
| dkato | 0:ee40da884cfc | 927 | sum += qlp_coeff[6] * data[i-7]; |
| dkato | 0:ee40da884cfc | 928 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 929 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 930 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 931 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 932 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 933 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 934 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 935 | } |
| dkato | 0:ee40da884cfc | 936 | } |
| dkato | 0:ee40da884cfc | 937 | } |
| dkato | 0:ee40da884cfc | 938 | else { |
| dkato | 0:ee40da884cfc | 939 | if(order == 6) { |
| dkato | 0:ee40da884cfc | 940 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 941 | sum = 0; |
| dkato | 0:ee40da884cfc | 942 | sum += qlp_coeff[5] * data[i-6]; |
| dkato | 0:ee40da884cfc | 943 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 944 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 945 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 946 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 947 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 948 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 949 | } |
| dkato | 0:ee40da884cfc | 950 | } |
| dkato | 0:ee40da884cfc | 951 | else { /* order == 5 */ |
| dkato | 0:ee40da884cfc | 952 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 953 | sum = 0; |
| dkato | 0:ee40da884cfc | 954 | sum += qlp_coeff[4] * data[i-5]; |
| dkato | 0:ee40da884cfc | 955 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 956 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 957 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 958 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 959 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 960 | } |
| dkato | 0:ee40da884cfc | 961 | } |
| dkato | 0:ee40da884cfc | 962 | } |
| dkato | 0:ee40da884cfc | 963 | } |
| dkato | 0:ee40da884cfc | 964 | else { |
| dkato | 0:ee40da884cfc | 965 | if(order > 2) { |
| dkato | 0:ee40da884cfc | 966 | if(order == 4) { |
| dkato | 0:ee40da884cfc | 967 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 968 | sum = 0; |
| dkato | 0:ee40da884cfc | 969 | sum += qlp_coeff[3] * data[i-4]; |
| dkato | 0:ee40da884cfc | 970 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 971 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 972 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 973 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 974 | } |
| dkato | 0:ee40da884cfc | 975 | } |
| dkato | 0:ee40da884cfc | 976 | else { /* order == 3 */ |
| dkato | 0:ee40da884cfc | 977 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 978 | sum = 0; |
| dkato | 0:ee40da884cfc | 979 | sum += qlp_coeff[2] * data[i-3]; |
| dkato | 0:ee40da884cfc | 980 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 981 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 982 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 983 | } |
| dkato | 0:ee40da884cfc | 984 | } |
| dkato | 0:ee40da884cfc | 985 | } |
| dkato | 0:ee40da884cfc | 986 | else { |
| dkato | 0:ee40da884cfc | 987 | if(order == 2) { |
| dkato | 0:ee40da884cfc | 988 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 989 | sum = 0; |
| dkato | 0:ee40da884cfc | 990 | sum += qlp_coeff[1] * data[i-2]; |
| dkato | 0:ee40da884cfc | 991 | sum += qlp_coeff[0] * data[i-1]; |
| dkato | 0:ee40da884cfc | 992 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 993 | } |
| dkato | 0:ee40da884cfc | 994 | } |
| dkato | 0:ee40da884cfc | 995 | else { /* order == 1 */ |
| dkato | 0:ee40da884cfc | 996 | for(i = 0; i < (int)data_len; i++) |
| dkato | 0:ee40da884cfc | 997 | data[i] = residual[i] + ((qlp_coeff[0] * data[i-1]) >> lp_quantization); |
| dkato | 0:ee40da884cfc | 998 | } |
| dkato | 0:ee40da884cfc | 999 | } |
| dkato | 0:ee40da884cfc | 1000 | } |
| dkato | 0:ee40da884cfc | 1001 | } |
| dkato | 0:ee40da884cfc | 1002 | else { /* order > 12 */ |
| dkato | 0:ee40da884cfc | 1003 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1004 | sum = 0; |
| dkato | 0:ee40da884cfc | 1005 | switch(order) { |
| dkato | 0:ee40da884cfc | 1006 | case 32: sum += qlp_coeff[31] * data[i-32]; |
| dkato | 0:ee40da884cfc | 1007 | case 31: sum += qlp_coeff[30] * data[i-31]; |
| dkato | 0:ee40da884cfc | 1008 | case 30: sum += qlp_coeff[29] * data[i-30]; |
| dkato | 0:ee40da884cfc | 1009 | case 29: sum += qlp_coeff[28] * data[i-29]; |
| dkato | 0:ee40da884cfc | 1010 | case 28: sum += qlp_coeff[27] * data[i-28]; |
| dkato | 0:ee40da884cfc | 1011 | case 27: sum += qlp_coeff[26] * data[i-27]; |
| dkato | 0:ee40da884cfc | 1012 | case 26: sum += qlp_coeff[25] * data[i-26]; |
| dkato | 0:ee40da884cfc | 1013 | case 25: sum += qlp_coeff[24] * data[i-25]; |
| dkato | 0:ee40da884cfc | 1014 | case 24: sum += qlp_coeff[23] * data[i-24]; |
| dkato | 0:ee40da884cfc | 1015 | case 23: sum += qlp_coeff[22] * data[i-23]; |
| dkato | 0:ee40da884cfc | 1016 | case 22: sum += qlp_coeff[21] * data[i-22]; |
| dkato | 0:ee40da884cfc | 1017 | case 21: sum += qlp_coeff[20] * data[i-21]; |
| dkato | 0:ee40da884cfc | 1018 | case 20: sum += qlp_coeff[19] * data[i-20]; |
| dkato | 0:ee40da884cfc | 1019 | case 19: sum += qlp_coeff[18] * data[i-19]; |
| dkato | 0:ee40da884cfc | 1020 | case 18: sum += qlp_coeff[17] * data[i-18]; |
| dkato | 0:ee40da884cfc | 1021 | case 17: sum += qlp_coeff[16] * data[i-17]; |
| dkato | 0:ee40da884cfc | 1022 | case 16: sum += qlp_coeff[15] * data[i-16]; |
| dkato | 0:ee40da884cfc | 1023 | case 15: sum += qlp_coeff[14] * data[i-15]; |
| dkato | 0:ee40da884cfc | 1024 | case 14: sum += qlp_coeff[13] * data[i-14]; |
| dkato | 0:ee40da884cfc | 1025 | case 13: sum += qlp_coeff[12] * data[i-13]; |
| dkato | 0:ee40da884cfc | 1026 | sum += qlp_coeff[11] * data[i-12]; |
| dkato | 0:ee40da884cfc | 1027 | sum += qlp_coeff[10] * data[i-11]; |
| dkato | 0:ee40da884cfc | 1028 | sum += qlp_coeff[ 9] * data[i-10]; |
| dkato | 0:ee40da884cfc | 1029 | sum += qlp_coeff[ 8] * data[i- 9]; |
| dkato | 0:ee40da884cfc | 1030 | sum += qlp_coeff[ 7] * data[i- 8]; |
| dkato | 0:ee40da884cfc | 1031 | sum += qlp_coeff[ 6] * data[i- 7]; |
| dkato | 0:ee40da884cfc | 1032 | sum += qlp_coeff[ 5] * data[i- 6]; |
| dkato | 0:ee40da884cfc | 1033 | sum += qlp_coeff[ 4] * data[i- 5]; |
| dkato | 0:ee40da884cfc | 1034 | sum += qlp_coeff[ 3] * data[i- 4]; |
| dkato | 0:ee40da884cfc | 1035 | sum += qlp_coeff[ 2] * data[i- 3]; |
| dkato | 0:ee40da884cfc | 1036 | sum += qlp_coeff[ 1] * data[i- 2]; |
| dkato | 0:ee40da884cfc | 1037 | sum += qlp_coeff[ 0] * data[i- 1]; |
| dkato | 0:ee40da884cfc | 1038 | } |
| dkato | 0:ee40da884cfc | 1039 | data[i] = residual[i] + (sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1040 | } |
| dkato | 0:ee40da884cfc | 1041 | } |
| dkato | 0:ee40da884cfc | 1042 | } |
| dkato | 0:ee40da884cfc | 1043 | #endif |
| dkato | 0:ee40da884cfc | 1044 | |
| dkato | 0:ee40da884cfc | 1045 | void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data) |
| dkato | 0:ee40da884cfc | 1046 | #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) |
| dkato | 0:ee40da884cfc | 1047 | { |
| dkato | 0:ee40da884cfc | 1048 | unsigned i, j; |
| dkato | 0:ee40da884cfc | 1049 | FLAC__int64 sum; |
| dkato | 0:ee40da884cfc | 1050 | const FLAC__int32 *r = residual, *history; |
| dkato | 0:ee40da884cfc | 1051 | |
| dkato | 0:ee40da884cfc | 1052 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE |
| dkato | 0:ee40da884cfc | 1053 | fprintf(stderr,"FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); |
| dkato | 0:ee40da884cfc | 1054 | for(i=0;i<order;i++) |
| dkato | 0:ee40da884cfc | 1055 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); |
| dkato | 0:ee40da884cfc | 1056 | fprintf(stderr,"\n"); |
| dkato | 0:ee40da884cfc | 1057 | #endif |
| dkato | 0:ee40da884cfc | 1058 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 1059 | |
| dkato | 0:ee40da884cfc | 1060 | for(i = 0; i < data_len; i++) { |
| dkato | 0:ee40da884cfc | 1061 | sum = 0; |
| dkato | 0:ee40da884cfc | 1062 | history = data; |
| dkato | 0:ee40da884cfc | 1063 | for(j = 0; j < order; j++) |
| dkato | 0:ee40da884cfc | 1064 | sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); |
| dkato | 0:ee40da884cfc | 1065 | if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { |
| dkato | 0:ee40da884cfc | 1066 | fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); |
| dkato | 0:ee40da884cfc | 1067 | break; |
| dkato | 0:ee40da884cfc | 1068 | } |
| dkato | 0:ee40da884cfc | 1069 | if(FLAC__bitmath_silog2_wide((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { |
| dkato | 0:ee40da884cfc | 1070 | 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))); |
| dkato | 0:ee40da884cfc | 1071 | break; |
| dkato | 0:ee40da884cfc | 1072 | } |
| dkato | 0:ee40da884cfc | 1073 | *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1074 | } |
| dkato | 0:ee40da884cfc | 1075 | } |
| dkato | 0:ee40da884cfc | 1076 | #else /* fully unrolled version for normal use */ |
| dkato | 0:ee40da884cfc | 1077 | { |
| dkato | 0:ee40da884cfc | 1078 | int i; |
| dkato | 0:ee40da884cfc | 1079 | FLAC__int64 sum; |
| dkato | 0:ee40da884cfc | 1080 | |
| dkato | 0:ee40da884cfc | 1081 | FLAC__ASSERT(order > 0); |
| dkato | 0:ee40da884cfc | 1082 | FLAC__ASSERT(order <= 32); |
| dkato | 0:ee40da884cfc | 1083 | |
| dkato | 0:ee40da884cfc | 1084 | /* |
| dkato | 0:ee40da884cfc | 1085 | * We do unique versions up to 12th order since that's the subset limit. |
| dkato | 0:ee40da884cfc | 1086 | * Also they are roughly ordered to match frequency of occurrence to |
| dkato | 0:ee40da884cfc | 1087 | * minimize branching. |
| dkato | 0:ee40da884cfc | 1088 | */ |
| dkato | 0:ee40da884cfc | 1089 | if(order <= 12) { |
| dkato | 0:ee40da884cfc | 1090 | if(order > 8) { |
| dkato | 0:ee40da884cfc | 1091 | if(order > 10) { |
| dkato | 0:ee40da884cfc | 1092 | if(order == 12) { |
| dkato | 0:ee40da884cfc | 1093 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1094 | sum = 0; |
| dkato | 0:ee40da884cfc | 1095 | sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; |
| dkato | 0:ee40da884cfc | 1096 | sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; |
| dkato | 0:ee40da884cfc | 1097 | sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 1098 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 1099 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 1100 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 1101 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 1102 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1103 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1104 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1105 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1106 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1107 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1108 | } |
| dkato | 0:ee40da884cfc | 1109 | } |
| dkato | 0:ee40da884cfc | 1110 | else { /* order == 11 */ |
| dkato | 0:ee40da884cfc | 1111 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1112 | sum = 0; |
| dkato | 0:ee40da884cfc | 1113 | sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; |
| dkato | 0:ee40da884cfc | 1114 | sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 1115 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 1116 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 1117 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 1118 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 1119 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1120 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1121 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1122 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1123 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1124 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1125 | } |
| dkato | 0:ee40da884cfc | 1126 | } |
| dkato | 0:ee40da884cfc | 1127 | } |
| dkato | 0:ee40da884cfc | 1128 | else { |
| dkato | 0:ee40da884cfc | 1129 | if(order == 10) { |
| dkato | 0:ee40da884cfc | 1130 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1131 | sum = 0; |
| dkato | 0:ee40da884cfc | 1132 | sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 1133 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 1134 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 1135 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 1136 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 1137 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1138 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1139 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1140 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1141 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1142 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1143 | } |
| dkato | 0:ee40da884cfc | 1144 | } |
| dkato | 0:ee40da884cfc | 1145 | else { /* order == 9 */ |
| dkato | 0:ee40da884cfc | 1146 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1147 | sum = 0; |
| dkato | 0:ee40da884cfc | 1148 | sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; |
| dkato | 0:ee40da884cfc | 1149 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 1150 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 1151 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 1152 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1153 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1154 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1155 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1156 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1157 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1158 | } |
| dkato | 0:ee40da884cfc | 1159 | } |
| dkato | 0:ee40da884cfc | 1160 | } |
| dkato | 0:ee40da884cfc | 1161 | } |
| dkato | 0:ee40da884cfc | 1162 | else if(order > 4) { |
| dkato | 0:ee40da884cfc | 1163 | if(order > 6) { |
| dkato | 0:ee40da884cfc | 1164 | if(order == 8) { |
| dkato | 0:ee40da884cfc | 1165 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1166 | sum = 0; |
| dkato | 0:ee40da884cfc | 1167 | sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; |
| dkato | 0:ee40da884cfc | 1168 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 1169 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 1170 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1171 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1172 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1173 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1174 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1175 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1176 | } |
| dkato | 0:ee40da884cfc | 1177 | } |
| dkato | 0:ee40da884cfc | 1178 | else { /* order == 7 */ |
| dkato | 0:ee40da884cfc | 1179 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1180 | sum = 0; |
| dkato | 0:ee40da884cfc | 1181 | sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; |
| dkato | 0:ee40da884cfc | 1182 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 1183 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1184 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1185 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1186 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1187 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1188 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1189 | } |
| dkato | 0:ee40da884cfc | 1190 | } |
| dkato | 0:ee40da884cfc | 1191 | } |
| dkato | 0:ee40da884cfc | 1192 | else { |
| dkato | 0:ee40da884cfc | 1193 | if(order == 6) { |
| dkato | 0:ee40da884cfc | 1194 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1195 | sum = 0; |
| dkato | 0:ee40da884cfc | 1196 | sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; |
| dkato | 0:ee40da884cfc | 1197 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1198 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1199 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1200 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1201 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1202 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1203 | } |
| dkato | 0:ee40da884cfc | 1204 | } |
| dkato | 0:ee40da884cfc | 1205 | else { /* order == 5 */ |
| dkato | 0:ee40da884cfc | 1206 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1207 | sum = 0; |
| dkato | 0:ee40da884cfc | 1208 | sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; |
| dkato | 0:ee40da884cfc | 1209 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1210 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1211 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1212 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1213 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1214 | } |
| dkato | 0:ee40da884cfc | 1215 | } |
| dkato | 0:ee40da884cfc | 1216 | } |
| dkato | 0:ee40da884cfc | 1217 | } |
| dkato | 0:ee40da884cfc | 1218 | else { |
| dkato | 0:ee40da884cfc | 1219 | if(order > 2) { |
| dkato | 0:ee40da884cfc | 1220 | if(order == 4) { |
| dkato | 0:ee40da884cfc | 1221 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1222 | sum = 0; |
| dkato | 0:ee40da884cfc | 1223 | sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; |
| dkato | 0:ee40da884cfc | 1224 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1225 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1226 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1227 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1228 | } |
| dkato | 0:ee40da884cfc | 1229 | } |
| dkato | 0:ee40da884cfc | 1230 | else { /* order == 3 */ |
| dkato | 0:ee40da884cfc | 1231 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1232 | sum = 0; |
| dkato | 0:ee40da884cfc | 1233 | sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; |
| dkato | 0:ee40da884cfc | 1234 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1235 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1236 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1237 | } |
| dkato | 0:ee40da884cfc | 1238 | } |
| dkato | 0:ee40da884cfc | 1239 | } |
| dkato | 0:ee40da884cfc | 1240 | else { |
| dkato | 0:ee40da884cfc | 1241 | if(order == 2) { |
| dkato | 0:ee40da884cfc | 1242 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1243 | sum = 0; |
| dkato | 0:ee40da884cfc | 1244 | sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; |
| dkato | 0:ee40da884cfc | 1245 | sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; |
| dkato | 0:ee40da884cfc | 1246 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1247 | } |
| dkato | 0:ee40da884cfc | 1248 | } |
| dkato | 0:ee40da884cfc | 1249 | else { /* order == 1 */ |
| dkato | 0:ee40da884cfc | 1250 | for(i = 0; i < (int)data_len; i++) |
| dkato | 0:ee40da884cfc | 1251 | data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1252 | } |
| dkato | 0:ee40da884cfc | 1253 | } |
| dkato | 0:ee40da884cfc | 1254 | } |
| dkato | 0:ee40da884cfc | 1255 | } |
| dkato | 0:ee40da884cfc | 1256 | else { /* order > 12 */ |
| dkato | 0:ee40da884cfc | 1257 | for(i = 0; i < (int)data_len; i++) { |
| dkato | 0:ee40da884cfc | 1258 | sum = 0; |
| dkato | 0:ee40da884cfc | 1259 | switch(order) { |
| dkato | 0:ee40da884cfc | 1260 | case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; |
| dkato | 0:ee40da884cfc | 1261 | case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; |
| dkato | 0:ee40da884cfc | 1262 | case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; |
| dkato | 0:ee40da884cfc | 1263 | case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; |
| dkato | 0:ee40da884cfc | 1264 | case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; |
| dkato | 0:ee40da884cfc | 1265 | case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; |
| dkato | 0:ee40da884cfc | 1266 | case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; |
| dkato | 0:ee40da884cfc | 1267 | case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; |
| dkato | 0:ee40da884cfc | 1268 | case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; |
| dkato | 0:ee40da884cfc | 1269 | case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; |
| dkato | 0:ee40da884cfc | 1270 | case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; |
| dkato | 0:ee40da884cfc | 1271 | case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; |
| dkato | 0:ee40da884cfc | 1272 | case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; |
| dkato | 0:ee40da884cfc | 1273 | case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; |
| dkato | 0:ee40da884cfc | 1274 | case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; |
| dkato | 0:ee40da884cfc | 1275 | case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; |
| dkato | 0:ee40da884cfc | 1276 | case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; |
| dkato | 0:ee40da884cfc | 1277 | case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; |
| dkato | 0:ee40da884cfc | 1278 | case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; |
| dkato | 0:ee40da884cfc | 1279 | case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; |
| dkato | 0:ee40da884cfc | 1280 | sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; |
| dkato | 0:ee40da884cfc | 1281 | sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; |
| dkato | 0:ee40da884cfc | 1282 | sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; |
| dkato | 0:ee40da884cfc | 1283 | sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; |
| dkato | 0:ee40da884cfc | 1284 | sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; |
| dkato | 0:ee40da884cfc | 1285 | sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; |
| dkato | 0:ee40da884cfc | 1286 | sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; |
| dkato | 0:ee40da884cfc | 1287 | sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; |
| dkato | 0:ee40da884cfc | 1288 | sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; |
| dkato | 0:ee40da884cfc | 1289 | sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; |
| dkato | 0:ee40da884cfc | 1290 | sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; |
| dkato | 0:ee40da884cfc | 1291 | sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; |
| dkato | 0:ee40da884cfc | 1292 | } |
| dkato | 0:ee40da884cfc | 1293 | data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); |
| dkato | 0:ee40da884cfc | 1294 | } |
| dkato | 0:ee40da884cfc | 1295 | } |
| dkato | 0:ee40da884cfc | 1296 | } |
| dkato | 0:ee40da884cfc | 1297 | #endif |
| dkato | 0:ee40da884cfc | 1298 | |
| dkato | 0:ee40da884cfc | 1299 | #if defined(_MSC_VER) |
| dkato | 0:ee40da884cfc | 1300 | #pragma warning ( default : 4028 ) |
| dkato | 0:ee40da884cfc | 1301 | #endif |
| dkato | 0:ee40da884cfc | 1302 | |
| dkato | 0:ee40da884cfc | 1303 | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
| dkato | 0:ee40da884cfc | 1304 | |
| dkato | 0:ee40da884cfc | 1305 | FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples) |
| dkato | 0:ee40da884cfc | 1306 | { |
| dkato | 0:ee40da884cfc | 1307 | FLAC__double error_scale; |
| dkato | 0:ee40da884cfc | 1308 | |
| dkato | 0:ee40da884cfc | 1309 | FLAC__ASSERT(total_samples > 0); |
| dkato | 0:ee40da884cfc | 1310 | |
| dkato | 0:ee40da884cfc | 1311 | error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples; |
| dkato | 0:ee40da884cfc | 1312 | |
| dkato | 0:ee40da884cfc | 1313 | return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale); |
| dkato | 0:ee40da884cfc | 1314 | } |
| dkato | 0:ee40da884cfc | 1315 | |
| dkato | 0:ee40da884cfc | 1316 | FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale) |
| dkato | 0:ee40da884cfc | 1317 | { |
| dkato | 0:ee40da884cfc | 1318 | if(lpc_error > 0.0) { |
| dkato | 0:ee40da884cfc | 1319 | FLAC__double bps = (FLAC__double)0.5 * log(error_scale * lpc_error) / M_LN2; |
| dkato | 0:ee40da884cfc | 1320 | if(bps >= 0.0) |
| dkato | 0:ee40da884cfc | 1321 | return bps; |
| dkato | 0:ee40da884cfc | 1322 | else |
| dkato | 0:ee40da884cfc | 1323 | return 0.0; |
| dkato | 0:ee40da884cfc | 1324 | } |
| dkato | 0:ee40da884cfc | 1325 | else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */ |
| dkato | 0:ee40da884cfc | 1326 | return 1e32; |
| dkato | 0:ee40da884cfc | 1327 | } |
| dkato | 0:ee40da884cfc | 1328 | else { |
| dkato | 0:ee40da884cfc | 1329 | return 0.0; |
| dkato | 0:ee40da884cfc | 1330 | } |
| dkato | 0:ee40da884cfc | 1331 | } |
| dkato | 0:ee40da884cfc | 1332 | |
| dkato | 0:ee40da884cfc | 1333 | unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order) |
| dkato | 0:ee40da884cfc | 1334 | { |
| dkato | 0:ee40da884cfc | 1335 | unsigned order, indx, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */ |
| dkato | 0:ee40da884cfc | 1336 | FLAC__double bits, best_bits, error_scale; |
| dkato | 0:ee40da884cfc | 1337 | |
| dkato | 0:ee40da884cfc | 1338 | FLAC__ASSERT(max_order > 0); |
| dkato | 0:ee40da884cfc | 1339 | FLAC__ASSERT(total_samples > 0); |
| dkato | 0:ee40da884cfc | 1340 | |
| dkato | 0:ee40da884cfc | 1341 | error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples; |
| dkato | 0:ee40da884cfc | 1342 | |
| dkato | 0:ee40da884cfc | 1343 | best_index = 0; |
| dkato | 0:ee40da884cfc | 1344 | best_bits = (unsigned)(-1); |
| dkato | 0:ee40da884cfc | 1345 | |
| dkato | 0:ee40da884cfc | 1346 | for(indx = 0, order = 1; indx < max_order; indx++, order++) { |
| dkato | 0:ee40da884cfc | 1347 | bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[indx], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * overhead_bits_per_order); |
| dkato | 0:ee40da884cfc | 1348 | if(bits < best_bits) { |
| dkato | 0:ee40da884cfc | 1349 | best_index = indx; |
| dkato | 0:ee40da884cfc | 1350 | best_bits = bits; |
| dkato | 0:ee40da884cfc | 1351 | } |
| dkato | 0:ee40da884cfc | 1352 | } |
| dkato | 0:ee40da884cfc | 1353 | |
| dkato | 0:ee40da884cfc | 1354 | return best_index+1; /* +1 since indx of lpc_error[] is order-1 */ |
| dkato | 0:ee40da884cfc | 1355 | } |
| dkato | 0:ee40da884cfc | 1356 | |
| dkato | 0:ee40da884cfc | 1357 | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ |
