annotate flacenc.c @ 3467:33af013504d5 libavcodec

optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients this will find the coefficients which minimize the sum of the squared errors, levinson-durbin recursion OTOH is only strictly correct if the autocorrelation matrix is a toeplitz matrix which it is only if the blocksize is infinite, this is also why applying a window (like the welch winodw we currently use) improves the lpc coefficients generated by levinson-durbin recursion ... optionally (use_lpc>2) support iterative linear least abs() solver using cholesky factorization with adjusted weights in each iteration compression gain for both is small, and multiple passes are of course dead slow
author michael
date Fri, 14 Jul 2006 18:48:38 +0000
parents 9cda085ab7cc
children c6071e607062
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
2 * FLAC audio encoder
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
3 * Copyright (c) 2006 Justin Ruggles <jruggle@earthlink.net>
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
4 *
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
9 *
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
13 * Lesser General Public License for more details.
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
14 *
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
18 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
19
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
20 #include "avcodec.h"
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
21 #include "bitstream.h"
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
22 #include "crc.h"
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
23 #include "golomb.h"
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
24 #include "lls.h"
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
25
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
26 #define FLAC_MAX_CH 8
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
27 #define FLAC_MIN_BLOCKSIZE 16
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
28 #define FLAC_MAX_BLOCKSIZE 65535
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
29
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
30 #define FLAC_SUBFRAME_CONSTANT 0
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
31 #define FLAC_SUBFRAME_VERBATIM 1
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
32 #define FLAC_SUBFRAME_FIXED 8
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
33 #define FLAC_SUBFRAME_LPC 32
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
34
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
35 #define FLAC_CHMODE_NOT_STEREO 0
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
36 #define FLAC_CHMODE_LEFT_RIGHT 1
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
37 #define FLAC_CHMODE_LEFT_SIDE 8
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
38 #define FLAC_CHMODE_RIGHT_SIDE 9
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
39 #define FLAC_CHMODE_MID_SIDE 10
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
40
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
41 #define ORDER_METHOD_EST 0
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
42 #define ORDER_METHOD_2LEVEL 1
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
43 #define ORDER_METHOD_4LEVEL 2
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
44 #define ORDER_METHOD_8LEVEL 3
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
45 #define ORDER_METHOD_SEARCH 4
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
46
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
47 #define FLAC_STREAMINFO_SIZE 34
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
48
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
49 #define MIN_LPC_ORDER 1
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
50 #define MAX_LPC_ORDER 32
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
51 #define MAX_FIXED_ORDER 4
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
52 #define MAX_PARTITION_ORDER 8
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
53 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
54 #define MAX_LPC_PRECISION 15
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
55 #define MAX_LPC_SHIFT 15
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
56 #define MAX_RICE_PARAM 14
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
57
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
58 typedef struct CompressionOptions {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
59 int compression_level;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
60 int block_time_ms;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
61 int use_lpc;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
62 int lpc_coeff_precision;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
63 int min_prediction_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
64 int max_prediction_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
65 int prediction_order_method;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
66 int min_partition_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
67 int max_partition_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
68 } CompressionOptions;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
69
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
70 typedef struct RiceContext {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
71 int porder;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
72 int params[MAX_PARTITIONS];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
73 } RiceContext;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
74
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
75 typedef struct FlacSubframe {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
76 int type;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
77 int type_code;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
78 int obits;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
79 int order;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
80 int32_t coefs[MAX_LPC_ORDER];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
81 int shift;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
82 RiceContext rc;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
83 int32_t samples[FLAC_MAX_BLOCKSIZE];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
84 int32_t residual[FLAC_MAX_BLOCKSIZE];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
85 } FlacSubframe;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
86
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
87 typedef struct FlacFrame {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
88 FlacSubframe subframes[FLAC_MAX_CH];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
89 int blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
90 int bs_code[2];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
91 uint8_t crc8;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
92 int ch_mode;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
93 } FlacFrame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
94
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
95 typedef struct FlacEncodeContext {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
96 PutBitContext pb;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
97 int channels;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
98 int ch_code;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
99 int samplerate;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
100 int sr_code[2];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
101 int blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
102 int max_framesize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
103 uint32_t frame_count;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
104 FlacFrame frame;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
105 CompressionOptions options;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
106 AVCodecContext *avctx;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
107 } FlacEncodeContext;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
108
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
109 static const int flac_samplerates[16] = {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
110 0, 0, 0, 0,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
111 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
112 0, 0, 0, 0
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
113 };
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
114
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
115 static const int flac_blocksizes[16] = {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
116 0,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
117 192,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
118 576, 1152, 2304, 4608,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
119 0, 0,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
120 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
121 };
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
122
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
123 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
124 * Writes streaminfo metadata block to byte array
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
125 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
126 static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
127 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
128 PutBitContext pb;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
129
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
130 memset(header, 0, FLAC_STREAMINFO_SIZE);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
131 init_put_bits(&pb, header, FLAC_STREAMINFO_SIZE);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
132
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
133 /* streaminfo metadata block */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
134 put_bits(&pb, 16, s->blocksize);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
135 put_bits(&pb, 16, s->blocksize);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
136 put_bits(&pb, 24, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
137 put_bits(&pb, 24, s->max_framesize);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
138 put_bits(&pb, 20, s->samplerate);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
139 put_bits(&pb, 3, s->channels-1);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
140 put_bits(&pb, 5, 15); /* bits per sample - 1 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
141 flush_put_bits(&pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
142 /* total samples = 0 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
143 /* MD5 signature = 0 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
144 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
145
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
146 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
147 * Sets blocksize based on samplerate
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
148 * Chooses the closest predefined blocksize >= BLOCK_TIME_MS milliseconds
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
149 */
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
150 static int select_blocksize(int samplerate, int block_time_ms)
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
151 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
152 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
153 int target;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
154 int blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
155
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
156 assert(samplerate > 0);
3354
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
157 blocksize = flac_blocksizes[1];
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
158 target = (samplerate * block_time_ms) / 1000;
3354
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
159 for(i=0; i<16; i++) {
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
160 if(target >= flac_blocksizes[i] && flac_blocksizes[i] > blocksize) {
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
161 blocksize = flac_blocksizes[i];
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
162 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
163 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
164 return blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
165 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
166
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
167 static int flac_encode_init(AVCodecContext *avctx)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
168 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
169 int freq = avctx->sample_rate;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
170 int channels = avctx->channels;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
171 FlacEncodeContext *s = avctx->priv_data;
3386
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
172 int i, level;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
173 uint8_t *streaminfo;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
174
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
175 s->avctx = avctx;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
176
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
177 if(avctx->sample_fmt != SAMPLE_FMT_S16) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
178 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
179 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
180
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
181 if(channels < 1 || channels > FLAC_MAX_CH) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
182 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
183 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
184 s->channels = channels;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
185 s->ch_code = s->channels-1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
186
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
187 /* find samplerate in table */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
188 if(freq < 1)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
189 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
190 for(i=4; i<12; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
191 if(freq == flac_samplerates[i]) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
192 s->samplerate = flac_samplerates[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
193 s->sr_code[0] = i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
194 s->sr_code[1] = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
195 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
196 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
197 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
198 /* if not in table, samplerate is non-standard */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
199 if(i == 12) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
200 if(freq % 1000 == 0 && freq < 255000) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
201 s->sr_code[0] = 12;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
202 s->sr_code[1] = freq / 1000;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
203 } else if(freq % 10 == 0 && freq < 655350) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
204 s->sr_code[0] = 14;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
205 s->sr_code[1] = freq / 10;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
206 } else if(freq < 65535) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
207 s->sr_code[0] = 13;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
208 s->sr_code[1] = freq;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
209 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
210 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
211 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
212 s->samplerate = freq;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
213 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
214
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
215 /* set compression option defaults based on avctx->compression_level */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
216 if(avctx->compression_level < 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
217 s->options.compression_level = 5;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
218 } else {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
219 s->options.compression_level = avctx->compression_level;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
220 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
221 av_log(avctx, AV_LOG_DEBUG, " compression: %d\n", s->options.compression_level);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
222
3386
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
223 level= s->options.compression_level;
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
224 if(level > 5) {
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
225 av_log(avctx, AV_LOG_ERROR, "invalid compression level: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
226 s->options.compression_level);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
227 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
228 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
229
3386
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
230 s->options.block_time_ms = ((int[]){ 27, 27, 27,105,105,105})[level];
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
231 s->options.use_lpc = ((int[]){ 0, 0, 0, 1, 1, 1})[level];
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
232 s->options.min_prediction_order= ((int[]){ 2, 0, 0, 1, 1, 1})[level];
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
233 s->options.max_prediction_order= ((int[]){ 3, 4, 4, 6, 8, 8})[level];
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
234 s->options.prediction_order_method = ORDER_METHOD_EST;
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
235 s->options.min_partition_order = ((int[]){ 2, 2, 0, 0, 0, 0})[level];
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
236 s->options.max_partition_order = ((int[]){ 2, 2, 3, 3, 3, 8})[level];
1b2a9377ff0d simplify
michael
parents: 3385
diff changeset
237
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
238 /* set compression option overrides from AVCodecContext */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
239 if(avctx->use_lpc >= 0) {
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
240 s->options.use_lpc = clip(avctx->use_lpc, 0, 11);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
241 }
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
242 if(s->options.use_lpc == 1)
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
243 av_log(avctx, AV_LOG_DEBUG, " use lpc: Levinson-Durbin recursion with Welch window\n");
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
244 else if(s->options.use_lpc > 1)
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
245 av_log(avctx, AV_LOG_DEBUG, " use lpc: Cholesky factorization\n");
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
246
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
247 if(avctx->min_prediction_order >= 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
248 if(s->options.use_lpc) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
249 if(avctx->min_prediction_order < MIN_LPC_ORDER ||
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
250 avctx->min_prediction_order > MAX_LPC_ORDER) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
251 av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
252 avctx->min_prediction_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
253 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
254 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
255 } else {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
256 if(avctx->min_prediction_order > MAX_FIXED_ORDER) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
257 av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
258 avctx->min_prediction_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
259 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
260 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
261 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
262 s->options.min_prediction_order = avctx->min_prediction_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
263 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
264 if(avctx->max_prediction_order >= 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
265 if(s->options.use_lpc) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
266 if(avctx->max_prediction_order < MIN_LPC_ORDER ||
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
267 avctx->max_prediction_order > MAX_LPC_ORDER) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
268 av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
269 avctx->max_prediction_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
270 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
271 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
272 } else {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
273 if(avctx->max_prediction_order > MAX_FIXED_ORDER) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
274 av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
275 avctx->max_prediction_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
276 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
277 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
278 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
279 s->options.max_prediction_order = avctx->max_prediction_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
280 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
281 if(s->options.max_prediction_order < s->options.min_prediction_order) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
282 av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
283 s->options.min_prediction_order, s->options.max_prediction_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
284 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
285 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
286 av_log(avctx, AV_LOG_DEBUG, " prediction order: %d, %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
287 s->options.min_prediction_order, s->options.max_prediction_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
288
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
289 if(avctx->prediction_order_method >= 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
290 if(avctx->prediction_order_method > ORDER_METHOD_SEARCH) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
291 av_log(avctx, AV_LOG_ERROR, "invalid prediction order method: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
292 avctx->prediction_order_method);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
293 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
294 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
295 s->options.prediction_order_method = avctx->prediction_order_method;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
296 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
297 switch(avctx->prediction_order_method) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
298 case ORDER_METHOD_EST: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
299 "estimate"); break;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
300 case ORDER_METHOD_2LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
301 "2-level"); break;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
302 case ORDER_METHOD_4LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
303 "4-level"); break;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
304 case ORDER_METHOD_8LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
305 "8-level"); break;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
306 case ORDER_METHOD_SEARCH: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
307 "full search"); break;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
308 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
309
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
310 if(avctx->min_partition_order >= 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
311 if(avctx->min_partition_order > MAX_PARTITION_ORDER) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
312 av_log(avctx, AV_LOG_ERROR, "invalid min partition order: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
313 avctx->min_partition_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
314 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
315 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
316 s->options.min_partition_order = avctx->min_partition_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
317 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
318 if(avctx->max_partition_order >= 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
319 if(avctx->max_partition_order > MAX_PARTITION_ORDER) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
320 av_log(avctx, AV_LOG_ERROR, "invalid max partition order: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
321 avctx->max_partition_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
322 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
323 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
324 s->options.max_partition_order = avctx->max_partition_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
325 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
326 if(s->options.max_partition_order < s->options.min_partition_order) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
327 av_log(avctx, AV_LOG_ERROR, "invalid partition orders: min=%d max=%d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
328 s->options.min_partition_order, s->options.max_partition_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
329 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
330 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
331 av_log(avctx, AV_LOG_DEBUG, " partition order: %d, %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
332 s->options.min_partition_order, s->options.max_partition_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
333
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
334 if(avctx->frame_size > 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
335 if(avctx->frame_size < FLAC_MIN_BLOCKSIZE ||
3442
5d133e59ecf2 allows user-settable block size and fixes related typo
jbr
parents: 3397
diff changeset
336 avctx->frame_size > FLAC_MAX_BLOCKSIZE) {
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
337 av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
338 avctx->frame_size);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
339 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
340 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
341 s->blocksize = avctx->frame_size;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
342 } else {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
343 s->blocksize = select_blocksize(s->samplerate, s->options.block_time_ms);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
344 avctx->frame_size = s->blocksize;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
345 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
346 av_log(avctx, AV_LOG_DEBUG, " block size: %d\n", s->blocksize);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
347
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
348 /* set LPC precision */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
349 if(avctx->lpc_coeff_precision > 0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
350 if(avctx->lpc_coeff_precision > MAX_LPC_PRECISION) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
351 av_log(avctx, AV_LOG_ERROR, "invalid lpc coeff precision: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
352 avctx->lpc_coeff_precision);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
353 return -1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
354 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
355 s->options.lpc_coeff_precision = avctx->lpc_coeff_precision;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
356 } else {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
357 /* select LPC precision based on block size */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
358 if( s->blocksize <= 192) s->options.lpc_coeff_precision = 7;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
359 else if(s->blocksize <= 384) s->options.lpc_coeff_precision = 8;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
360 else if(s->blocksize <= 576) s->options.lpc_coeff_precision = 9;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
361 else if(s->blocksize <= 1152) s->options.lpc_coeff_precision = 10;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
362 else if(s->blocksize <= 2304) s->options.lpc_coeff_precision = 11;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
363 else if(s->blocksize <= 4608) s->options.lpc_coeff_precision = 12;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
364 else if(s->blocksize <= 8192) s->options.lpc_coeff_precision = 13;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
365 else if(s->blocksize <= 16384) s->options.lpc_coeff_precision = 14;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
366 else s->options.lpc_coeff_precision = 15;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
367 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
368 av_log(avctx, AV_LOG_DEBUG, " lpc precision: %d\n",
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
369 s->options.lpc_coeff_precision);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
370
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
371 /* set maximum encoded frame size in verbatim mode */
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
372 if(s->channels == 2) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
373 s->max_framesize = 14 + ((s->blocksize * 33 + 7) >> 3);
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
374 } else {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
375 s->max_framesize = 14 + (s->blocksize * s->channels * 2);
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
376 }
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
377
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
378 streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
379 write_streaminfo(s, streaminfo);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
380 avctx->extradata = streaminfo;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
381 avctx->extradata_size = FLAC_STREAMINFO_SIZE;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
382
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
383 s->frame_count = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
384
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
385 avctx->coded_frame = avcodec_alloc_frame();
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
386 avctx->coded_frame->key_frame = 1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
387
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
388 return 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
389 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
390
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
391 static void init_frame(FlacEncodeContext *s)
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
392 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
393 int i, ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
394 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
395
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
396 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
397
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
398 for(i=0; i<16; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
399 if(s->blocksize == flac_blocksizes[i]) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
400 frame->blocksize = flac_blocksizes[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
401 frame->bs_code[0] = i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
402 frame->bs_code[1] = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
403 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
404 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
405 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
406 if(i == 16) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
407 frame->blocksize = s->blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
408 if(frame->blocksize <= 256) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
409 frame->bs_code[0] = 6;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
410 frame->bs_code[1] = frame->blocksize-1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
411 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
412 frame->bs_code[0] = 7;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
413 frame->bs_code[1] = frame->blocksize-1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
414 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
415 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
416
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
417 for(ch=0; ch<s->channels; ch++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
418 frame->subframes[ch].obits = 16;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
419 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
420 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
421
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
422 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
423 * Copy channel-interleaved input samples into separate subframes
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
424 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
425 static void copy_samples(FlacEncodeContext *s, int16_t *samples)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
426 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
427 int i, j, ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
428 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
429
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
430 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
431 for(i=0,j=0; i<frame->blocksize; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
432 for(ch=0; ch<s->channels; ch++,j++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
433 frame->subframes[ch].samples[i] = samples[j];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
434 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
435 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
436 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
437
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
438
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
439 #define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k)))
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
440
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
441 static int find_optimal_param(uint32_t sum, int n)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
442 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
443 int k, k_opt;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
444 uint32_t nbits[MAX_RICE_PARAM+1];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
445
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
446 k_opt = 0;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
447 nbits[0] = UINT32_MAX;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
448 for(k=0; k<=MAX_RICE_PARAM; k++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
449 nbits[k] = rice_encode_count(sum, n, k);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
450 if(nbits[k] < nbits[k_opt]) {
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
451 k_opt = k;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
452 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
453 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
454 return k_opt;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
455 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
456
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
457 static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder,
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
458 uint32_t *sums, int n, int pred_order)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
459 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
460 int i;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
461 int k, cnt, part;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
462 uint32_t all_bits;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
463
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
464 part = (1 << porder);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
465 all_bits = 0;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
466
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
467 cnt = (n >> porder) - pred_order;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
468 for(i=0; i<part; i++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
469 if(i == 1) cnt = (n >> porder);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
470 k = find_optimal_param(sums[i], cnt);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
471 rc->params[i] = k;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
472 all_bits += rice_encode_count(sums[i], cnt, k);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
473 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
474 all_bits += (4 * part);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
475
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
476 rc->porder = porder;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
477
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
478 return all_bits;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
479 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
480
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
481 static void calc_sums(int pmin, int pmax, uint32_t *data, int n, int pred_order,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
482 uint32_t sums[][MAX_PARTITIONS])
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
483 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
484 int i, j;
3384
573fed4bf20f simplify
michael
parents: 3365
diff changeset
485 int parts;
573fed4bf20f simplify
michael
parents: 3365
diff changeset
486 uint32_t *res, *res_end;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
487
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
488 /* sums for highest level */
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
489 parts = (1 << pmax);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
490 res = &data[pred_order];
3384
573fed4bf20f simplify
michael
parents: 3365
diff changeset
491 res_end = &data[n >> pmax];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
492 for(i=0; i<parts; i++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
493 sums[pmax][i] = 0;
3384
573fed4bf20f simplify
michael
parents: 3365
diff changeset
494 while(res < res_end){
573fed4bf20f simplify
michael
parents: 3365
diff changeset
495 sums[pmax][i] += *(res++);
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
496 }
3384
573fed4bf20f simplify
michael
parents: 3365
diff changeset
497 res_end+= n >> pmax;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
498 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
499 /* sums for lower levels */
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
500 for(i=pmax-1; i>=pmin; i--) {
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
501 parts = (1 << i);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
502 for(j=0; j<parts; j++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
503 sums[i][j] = sums[i+1][2*j] + sums[i+1][2*j+1];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
504 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
505 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
506 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
507
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
508 static uint32_t calc_rice_params(RiceContext *rc, int pmin, int pmax,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
509 int32_t *data, int n, int pred_order)
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
510 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
511 int i;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
512 uint32_t bits[MAX_PARTITION_ORDER+1];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
513 int opt_porder;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
514 RiceContext tmp_rc;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
515 uint32_t *udata;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
516 uint32_t sums[MAX_PARTITION_ORDER+1][MAX_PARTITIONS];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
517
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
518 assert(pmin >= 0 && pmin <= MAX_PARTITION_ORDER);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
519 assert(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
520 assert(pmin <= pmax);
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
521
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
522 udata = av_malloc(n * sizeof(uint32_t));
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
523 for(i=0; i<n; i++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
524 udata[i] = (2*data[i]) ^ (data[i]>>31);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
525 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
526
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
527 calc_sums(pmin, pmax, udata, n, pred_order, sums);
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
528
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
529 opt_porder = pmin;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
530 bits[pmin] = UINT32_MAX;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
531 for(i=pmin; i<=pmax; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
532 bits[i] = calc_optimal_rice_params(&tmp_rc, i, sums[i], n, pred_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
533 if(bits[i] <= bits[opt_porder]) {
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
534 opt_porder = i;
3387
92fabe8c1422 dont use memcpy for copying structs
michael
parents: 3386
diff changeset
535 *rc= tmp_rc;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
536 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
537 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
538
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
539 av_freep(&udata);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
540 return bits[opt_porder];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
541 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
542
3397
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
543 static int get_max_p_order(int max_porder, int n, int order)
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
544 {
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
545 int porder = FFMIN(max_porder, av_log2(n^(n-1)));
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
546 if(order > 0)
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
547 porder = FFMIN(porder, av_log2(n/order));
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
548 return porder;
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
549 }
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
550
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
551 static uint32_t calc_rice_params_fixed(RiceContext *rc, int pmin, int pmax,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
552 int32_t *data, int n, int pred_order,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
553 int bps)
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
554 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
555 uint32_t bits;
3397
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
556 pmin = get_max_p_order(pmin, n, pred_order);
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
557 pmax = get_max_p_order(pmax, n, pred_order);
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
558 bits = pred_order*bps + 6;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
559 bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
560 return bits;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
561 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
562
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
563 static uint32_t calc_rice_params_lpc(RiceContext *rc, int pmin, int pmax,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
564 int32_t *data, int n, int pred_order,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
565 int bps, int precision)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
566 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
567 uint32_t bits;
3397
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
568 pmin = get_max_p_order(pmin, n, pred_order);
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
569 pmax = get_max_p_order(pmax, n, pred_order);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
570 bits = pred_order*bps + 4 + 5 + pred_order*precision + 6;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
571 bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order);
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
572 return bits;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
573 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
574
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
575 /**
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
576 * Apply Welch window function to audio block
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
577 */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
578 static void apply_welch_window(const int32_t *data, int len, double *w_data)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
579 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
580 int i, n2;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
581 double w;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
582 double c;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
583
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
584 n2 = (len >> 1);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
585 c = 2.0 / (len - 1.0);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
586 for(i=0; i<n2; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
587 w = c - i - 1.0;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
588 w = 1.0 - (w * w);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
589 w_data[i] = data[i] * w;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
590 w_data[len-1-i] = data[len-1-i] * w;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
591 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
592 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
593
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
594 /**
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
595 * Calculates autocorrelation data from audio samples
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
596 * A Welch window function is applied before calculation.
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
597 */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
598 static void compute_autocorr(const int32_t *data, int len, int lag,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
599 double *autoc)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
600 {
3388
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
601 int i, lag_ptr;
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
602 double tmp[len + lag];
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
603 double *data1= tmp + lag;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
604
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
605 apply_welch_window(data, len, data1);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
606
3388
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
607 for(i=0; i<lag; i++){
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
608 autoc[i] = 1.0;
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
609 data1[i-lag]= 0.0;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
610 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
611
3388
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
612 for(i=0; i<len; i++){
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
613 for(lag_ptr= i-lag; lag_ptr<=i; lag_ptr++){
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
614 autoc[i-lag_ptr] += data1[i] * data1[lag_ptr];
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
615 }
22c7b4c96c2d simplify compute_autocorr
michael
parents: 3387
diff changeset
616 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
617 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
618
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
619 /**
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
620 * Levinson-Durbin recursion.
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
621 * Produces LPC coefficients from autocorrelation data.
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
622 */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
623 static void compute_lpc_coefs(const double *autoc, int max_order,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
624 double lpc[][MAX_LPC_ORDER], double *ref)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
625 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
626 int i, j, i2;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
627 double r, err, tmp;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
628 double lpc_tmp[MAX_LPC_ORDER];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
629
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
630 for(i=0; i<max_order; i++) lpc_tmp[i] = 0;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
631 err = autoc[0];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
632
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
633 for(i=0; i<max_order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
634 r = -autoc[i+1];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
635 for(j=0; j<i; j++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
636 r -= lpc_tmp[j] * autoc[i-j];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
637 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
638 r /= err;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
639 ref[i] = fabs(r);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
640
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
641 err *= 1.0 - (r * r);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
642
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
643 i2 = (i >> 1);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
644 lpc_tmp[i] = r;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
645 for(j=0; j<i2; j++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
646 tmp = lpc_tmp[j];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
647 lpc_tmp[j] += r * lpc_tmp[i-1-j];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
648 lpc_tmp[i-1-j] += r * tmp;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
649 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
650 if(i & 1) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
651 lpc_tmp[j] += lpc_tmp[j] * r;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
652 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
653
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
654 for(j=0; j<=i; j++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
655 lpc[i][j] = -lpc_tmp[j];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
656 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
657 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
658 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
659
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
660 /**
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
661 * Quantize LPC coefficients
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
662 */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
663 static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
664 int32_t *lpc_out, int *shift)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
665 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
666 int i;
3464
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
667 double cmax, error;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
668 int32_t qmax;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
669 int sh;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
670
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
671 /* define maximum levels */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
672 qmax = (1 << (precision - 1)) - 1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
673
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
674 /* find maximum coefficient value */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
675 cmax = 0.0;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
676 for(i=0; i<order; i++) {
3389
de8cdb05117f simplify
michael
parents: 3388
diff changeset
677 cmax= FFMAX(cmax, fabs(lpc_in[i]));
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
678 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
679
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
680 /* if maximum value quantizes to zero, return all zeros */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
681 if(cmax * (1 << MAX_LPC_SHIFT) < 1.0) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
682 *shift = 0;
3389
de8cdb05117f simplify
michael
parents: 3388
diff changeset
683 memset(lpc_out, 0, sizeof(int32_t) * order);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
684 return;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
685 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
686
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
687 /* calculate level shift which scales max coeff to available bits */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
688 sh = MAX_LPC_SHIFT;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
689 while((cmax * (1 << sh) > qmax) && (sh > 0)) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
690 sh--;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
691 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
692
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
693 /* since negative shift values are unsupported in decoder, scale down
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
694 coefficients instead */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
695 if(sh == 0 && cmax > qmax) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
696 double scale = ((double)qmax) / cmax;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
697 for(i=0; i<order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
698 lpc_in[i] *= scale;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
699 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
700 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
701
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
702 /* output quantized coefficients and level shift */
3464
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
703 error=0;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
704 for(i=0; i<order; i++) {
3464
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
705 error += lpc_in[i] * (1 << sh);
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
706 lpc_out[i] = clip(lrintf(error), -qmax, qmax);
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
707 error -= lpc_out[i];
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
708 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
709 *shift = sh;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
710 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
711
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
712 static int estimate_best_order(double *ref, int max_order)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
713 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
714 int i, est;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
715
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
716 est = 1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
717 for(i=max_order-1; i>=0; i--) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
718 if(ref[i] > 0.10) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
719 est = i+1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
720 break;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
721 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
722 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
723 return est;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
724 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
725
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
726 /**
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
727 * Calculate LPC coefficients for multiple orders
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
728 */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
729 static int lpc_calc_coefs(const int32_t *samples, int blocksize, int max_order,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
730 int precision, int32_t coefs[][MAX_LPC_ORDER],
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
731 int *shift, int use_lpc)
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
732 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
733 double autoc[MAX_LPC_ORDER+1];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
734 double ref[MAX_LPC_ORDER];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
735 double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
736 int i, j, pass;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
737 int opt_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
738
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
739 assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
740
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
741 if(use_lpc == 1){
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
742 compute_autocorr(samples, blocksize, max_order+1, autoc);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
743
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
744 compute_lpc_coefs(autoc, max_order, lpc, ref);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
745
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
746 opt_order = estimate_best_order(ref, max_order);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
747 }else{
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
748 LLSModel m[2];
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
749 double var[MAX_LPC_ORDER+1], eval;
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
750
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
751 for(pass=0; pass<use_lpc-1; pass++){
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
752 av_init_lls(&m[pass&1], max_order/*3*/);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
753
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
754 for(i=max_order; i<blocksize; i++){
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
755 for(j=0; j<=max_order; j++)
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
756 var[j]= samples[i-j];
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
757
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
758 if(pass){
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
759 eval= av_evaluate_lls(&m[(pass-1)&1], var+1);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
760 eval= (512>>pass) + fabs(eval - var[0]);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
761 for(j=0; j<=max_order; j++)
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
762 var[j]= samples[i-j] / sqrt(eval);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
763 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
764
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
765 av_update_lls(&m[pass&1], var, 1.0);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
766 }
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
767 av_solve_lls(&m[pass&1], 0.001);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
768 opt_order= max_order; //FIXME
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
769 }
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
770
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
771 for(i=0; i<opt_order; i++)
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
772 lpc[opt_order-1][i]= m[(pass-1)&1].coeff[i];
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
773 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
774
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
775 i = opt_order-1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
776 quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i]);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
777
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
778 return opt_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
779 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
780
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
781
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
782 static void encode_residual_verbatim(int32_t *res, int32_t *smp, int n)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
783 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
784 assert(n > 0);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
785 memcpy(res, smp, n * sizeof(int32_t));
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
786 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
787
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
788 static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
789 int order)
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
790 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
791 int i;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
792
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
793 for(i=0; i<order; i++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
794 res[i] = smp[i];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
795 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
796
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
797 if(order==0){
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
798 for(i=order; i<n; i++)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
799 res[i]= smp[i];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
800 }else if(order==1){
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
801 for(i=order; i<n; i++)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
802 res[i]= smp[i] - smp[i-1];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
803 }else if(order==2){
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
804 for(i=order; i<n; i++)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
805 res[i]= smp[i] - 2*smp[i-1] + smp[i-2];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
806 }else if(order==3){
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
807 for(i=order; i<n; i++)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
808 res[i]= smp[i] - 3*smp[i-1] + 3*smp[i-2] - smp[i-3];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
809 }else{
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
810 for(i=order; i<n; i++)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
811 res[i]= smp[i] - 4*smp[i-1] + 6*smp[i-2] - 4*smp[i-3] + smp[i-4];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
812 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
813 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
814
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
815 static void encode_residual_lpc(int32_t *res, const int32_t *smp, int n,
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
816 int order, const int32_t *coefs, int shift)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
817 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
818 int i, j;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
819 int32_t pred;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
820
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
821 for(i=0; i<order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
822 res[i] = smp[i];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
823 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
824 for(i=order; i<n; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
825 pred = 0;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
826 for(j=0; j<order; j++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
827 pred += coefs[j] * smp[i-j-1];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
828 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
829 res[i] = smp[i] - (pred >> shift);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
830 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
831 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
832
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
833 static int encode_residual(FlacEncodeContext *ctx, int ch)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
834 {
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
835 int i, n;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
836 int min_order, max_order, opt_order, precision;
3397
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
837 int min_porder, max_porder;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
838 FlacFrame *frame;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
839 FlacSubframe *sub;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
840 int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
841 int shift[MAX_LPC_ORDER];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
842 int32_t *res, *smp;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
843
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
844 frame = &ctx->frame;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
845 sub = &frame->subframes[ch];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
846 res = sub->residual;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
847 smp = sub->samples;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
848 n = frame->blocksize;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
849
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
850 /* CONSTANT */
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
851 for(i=1; i<n; i++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
852 if(smp[i] != smp[0]) break;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
853 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
854 if(i == n) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
855 sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
856 res[0] = smp[0];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
857 return sub->obits;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
858 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
859
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
860 /* VERBATIM */
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
861 if(n < 5) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
862 sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
863 encode_residual_verbatim(res, smp, n);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
864 return sub->obits * n;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
865 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
866
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
867 min_order = ctx->options.min_prediction_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
868 max_order = ctx->options.max_prediction_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
869 min_porder = ctx->options.min_partition_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
870 max_porder = ctx->options.max_partition_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
871 precision = ctx->options.lpc_coeff_precision;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
872
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
873 /* FIXED */
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
874 if(!ctx->options.use_lpc || max_order == 0 || (n <= max_order)) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
875 uint32_t bits[MAX_FIXED_ORDER+1];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
876 if(max_order > MAX_FIXED_ORDER) max_order = MAX_FIXED_ORDER;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
877 opt_order = 0;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
878 bits[0] = UINT32_MAX;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
879 for(i=min_order; i<=max_order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
880 encode_residual_fixed(res, smp, n, i);
3397
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
881 bits[i] = calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res,
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
882 n, i, sub->obits);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
883 if(bits[i] < bits[opt_order]) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
884 opt_order = i;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
885 }
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
886 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
887 sub->order = opt_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
888 sub->type = FLAC_SUBFRAME_FIXED;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
889 sub->type_code = sub->type | sub->order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
890 if(sub->order != max_order) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
891 encode_residual_fixed(res, smp, n, sub->order);
3397
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
892 return calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res, n,
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
893 sub->order, sub->obits);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
894 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
895 return bits[sub->order];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
896 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
897
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
898 /* LPC */
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
899 sub->order = lpc_calc_coefs(smp, n, max_order, precision, coefs, shift, ctx->options.use_lpc);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
900 sub->type = FLAC_SUBFRAME_LPC;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
901 sub->type_code = sub->type | (sub->order-1);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
902 sub->shift = shift[sub->order-1];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
903 for(i=0; i<sub->order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
904 sub->coefs[i] = coefs[sub->order-1][i];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
905 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
906 encode_residual_lpc(res, smp, n, sub->order, sub->coefs, sub->shift);
3397
bdfc530c417c porder patch by (Justin Ruggles jruggle a t earthlink d ot net)
michael
parents: 3390
diff changeset
907 return calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n, sub->order,
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
908 sub->obits, precision);
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
909 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
910
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
911 static int encode_residual_v(FlacEncodeContext *ctx, int ch)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
912 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
913 int i, n;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
914 FlacFrame *frame;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
915 FlacSubframe *sub;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
916 int32_t *res, *smp;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
917
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
918 frame = &ctx->frame;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
919 sub = &frame->subframes[ch];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
920 res = sub->residual;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
921 smp = sub->samples;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
922 n = frame->blocksize;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
923
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
924 /* CONSTANT */
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
925 for(i=1; i<n; i++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
926 if(smp[i] != smp[0]) break;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
927 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
928 if(i == n) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
929 sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
930 res[0] = smp[0];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
931 return sub->obits;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
932 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
933
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
934 /* VERBATIM */
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
935 sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
936 encode_residual_verbatim(res, smp, n);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
937 return sub->obits * n;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
938 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
939
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
940 static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
941 {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
942 int i, best;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
943 int32_t lt, rt;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
944 uint64_t sum[4];
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
945 uint64_t score[4];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
946 int k;
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
947
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
948 /* calculate sum of 2nd order residual for each channel */
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
949 sum[0] = sum[1] = sum[2] = sum[3] = 0;
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
950 for(i=2; i<n; i++) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
951 lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2];
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
952 rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
953 sum[2] += ABS((lt + rt) >> 1);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
954 sum[3] += ABS(lt - rt);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
955 sum[0] += ABS(lt);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
956 sum[1] += ABS(rt);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
957 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
958 /* estimate bit counts */
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
959 for(i=0; i<4; i++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
960 k = find_optimal_param(2*sum[i], n);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
961 sum[i] = rice_encode_count(2*sum[i], n, k);
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
962 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
963
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
964 /* calculate score for each mode */
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
965 score[0] = sum[0] + sum[1];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
966 score[1] = sum[0] + sum[3];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
967 score[2] = sum[1] + sum[3];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
968 score[3] = sum[2] + sum[3];
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
969
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
970 /* return mode with lowest score */
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
971 best = 0;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
972 for(i=1; i<4; i++) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
973 if(score[i] < score[best]) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
974 best = i;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
975 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
976 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
977 if(best == 0) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
978 return FLAC_CHMODE_LEFT_RIGHT;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
979 } else if(best == 1) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
980 return FLAC_CHMODE_LEFT_SIDE;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
981 } else if(best == 2) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
982 return FLAC_CHMODE_RIGHT_SIDE;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
983 } else {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
984 return FLAC_CHMODE_MID_SIDE;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
985 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
986 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
987
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
988 /**
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
989 * Perform stereo channel decorrelation
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
990 */
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
991 static void channel_decorrelation(FlacEncodeContext *ctx)
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
992 {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
993 FlacFrame *frame;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
994 int32_t *left, *right;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
995 int i, n;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
996
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
997 frame = &ctx->frame;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
998 n = frame->blocksize;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
999 left = frame->subframes[0].samples;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1000 right = frame->subframes[1].samples;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1001
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1002 if(ctx->channels != 2) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1003 frame->ch_mode = FLAC_CHMODE_NOT_STEREO;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1004 return;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1005 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1006
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1007 frame->ch_mode = estimate_stereo_mode(left, right, n);
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1008
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1009 /* perform decorrelation and adjust bits-per-sample */
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1010 if(frame->ch_mode == FLAC_CHMODE_LEFT_RIGHT) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1011 return;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1012 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1013 if(frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1014 int32_t tmp;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1015 for(i=0; i<n; i++) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1016 tmp = left[i];
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1017 left[i] = (tmp + right[i]) >> 1;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1018 right[i] = tmp - right[i];
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1019 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1020 frame->subframes[1].obits++;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1021 } else if(frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1022 for(i=0; i<n; i++) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1023 right[i] = left[i] - right[i];
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1024 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1025 frame->subframes[1].obits++;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1026 } else {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1027 for(i=0; i<n; i++) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1028 left[i] -= right[i];
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1029 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1030 frame->subframes[0].obits++;
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1031 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1032 }
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1033
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1034 static void put_sbits(PutBitContext *pb, int bits, int32_t val)
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1035 {
3354
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
1036 assert(bits >= 0 && bits <= 31);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1037
3354
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
1038 put_bits(pb, bits, val & ((1<<bits)-1));
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1039 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1040
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1041 static void write_utf8(PutBitContext *pb, uint32_t val)
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1042 {
3354
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
1043 int bytes, shift;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1044
3354
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
1045 if(val < 0x80){
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1046 put_bits(pb, 8, val);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1047 return;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1048 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1049
3357
michael
parents: 3354
diff changeset
1050 bytes= (av_log2(val)+4) / 5;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1051 shift = (bytes - 1) * 6;
3354
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
1052 put_bits(pb, 8, (256 - (256>>bytes)) | (val >> shift));
ba80e4de976b simplify & optimize things a little
michael
parents: 3353
diff changeset
1053 while(shift >= 6){
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1054 shift -= 6;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1055 put_bits(pb, 8, 0x80 | ((val >> shift) & 0x3F));
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1056 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1057 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1058
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1059 static void output_frame_header(FlacEncodeContext *s)
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1060 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1061 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1062 int crc;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1063
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1064 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1065
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1066 put_bits(&s->pb, 16, 0xFFF8);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1067 put_bits(&s->pb, 4, frame->bs_code[0]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1068 put_bits(&s->pb, 4, s->sr_code[0]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1069 if(frame->ch_mode == FLAC_CHMODE_NOT_STEREO) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1070 put_bits(&s->pb, 4, s->ch_code);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1071 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1072 put_bits(&s->pb, 4, frame->ch_mode);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1073 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1074 put_bits(&s->pb, 3, 4); /* bits-per-sample code */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1075 put_bits(&s->pb, 1, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1076 write_utf8(&s->pb, s->frame_count);
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1077 if(frame->bs_code[0] == 6) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1078 put_bits(&s->pb, 8, frame->bs_code[1]);
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1079 } else if(frame->bs_code[0] == 7) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1080 put_bits(&s->pb, 16, frame->bs_code[1]);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1081 }
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1082 if(s->sr_code[0] == 12) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1083 put_bits(&s->pb, 8, s->sr_code[1]);
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1084 } else if(s->sr_code[0] > 12) {
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1085 put_bits(&s->pb, 16, s->sr_code[1]);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1086 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1087 flush_put_bits(&s->pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1088 crc = av_crc(av_crc07, 0, s->pb.buf, put_bits_count(&s->pb)>>3);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1089 put_bits(&s->pb, 8, crc);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1090 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1091
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1092 static void output_subframe_constant(FlacEncodeContext *s, int ch)
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1093 {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1094 FlacSubframe *sub;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1095 int32_t res;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1096
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1097 sub = &s->frame.subframes[ch];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1098 res = sub->residual[0];
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1099 put_sbits(&s->pb, sub->obits, res);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1100 }
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1101
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1102 static void output_subframe_verbatim(FlacEncodeContext *s, int ch)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1103 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1104 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1105 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1106 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1107 int32_t res;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1108
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1109 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1110 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1111
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1112 for(i=0; i<frame->blocksize; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1113 res = sub->residual[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1114 put_sbits(&s->pb, sub->obits, res);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1115 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1116 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1117
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1118 static void output_residual(FlacEncodeContext *ctx, int ch)
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1119 {
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1120 int i, j, p, n, parts;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1121 int k, porder, psize, res_cnt;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1122 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1123 FlacSubframe *sub;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1124 int32_t *res;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1125
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1126 frame = &ctx->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1127 sub = &frame->subframes[ch];
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1128 res = sub->residual;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1129 n = frame->blocksize;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1130
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1131 /* rice-encoded block */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1132 put_bits(&ctx->pb, 2, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1133
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1134 /* partition order */
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1135 porder = sub->rc.porder;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1136 psize = n >> porder;
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1137 parts = (1 << porder);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1138 put_bits(&ctx->pb, 4, porder);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1139 res_cnt = psize - sub->order;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1140
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1141 /* residual */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1142 j = sub->order;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1143 for(p=0; p<parts; p++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1144 k = sub->rc.params[p];
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1145 put_bits(&ctx->pb, 4, k);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1146 if(p == 1) res_cnt = psize;
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1147 for(i=0; i<res_cnt && j<n; i++, j++) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1148 set_sr_golomb_flac(&ctx->pb, res[j], k, INT32_MAX, 0);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1149 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1150 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1151 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1152
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1153 static void output_subframe_fixed(FlacEncodeContext *ctx, int ch)
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1154 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1155 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1156 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1157 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1158
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1159 frame = &ctx->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1160 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1161
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1162 /* warm-up samples */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1163 for(i=0; i<sub->order; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1164 put_sbits(&ctx->pb, sub->obits, sub->residual[i]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1165 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1166
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1167 /* residual */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1168 output_residual(ctx, ch);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1169 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1170
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1171 static void output_subframe_lpc(FlacEncodeContext *ctx, int ch)
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1172 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1173 int i, cbits;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1174 FlacFrame *frame;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1175 FlacSubframe *sub;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1176
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1177 frame = &ctx->frame;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1178 sub = &frame->subframes[ch];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1179
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1180 /* warm-up samples */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1181 for(i=0; i<sub->order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1182 put_sbits(&ctx->pb, sub->obits, sub->residual[i]);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1183 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1184
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1185 /* LPC coefficients */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1186 cbits = ctx->options.lpc_coeff_precision;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1187 put_bits(&ctx->pb, 4, cbits-1);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1188 put_sbits(&ctx->pb, 5, sub->shift);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1189 for(i=0; i<sub->order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1190 put_sbits(&ctx->pb, cbits, sub->coefs[i]);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1191 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1192
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1193 /* residual */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1194 output_residual(ctx, ch);
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1195 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1196
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1197 static void output_subframes(FlacEncodeContext *s)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1198 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1199 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1200 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1201 int ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1202
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1203 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1204
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1205 for(ch=0; ch<s->channels; ch++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1206 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1207
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1208 /* subframe header */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1209 put_bits(&s->pb, 1, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1210 put_bits(&s->pb, 6, sub->type_code);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1211 put_bits(&s->pb, 1, 0); /* no wasted bits */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1212
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1213 /* subframe */
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1214 if(sub->type == FLAC_SUBFRAME_CONSTANT) {
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1215 output_subframe_constant(s, ch);
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1216 } else if(sub->type == FLAC_SUBFRAME_VERBATIM) {
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1217 output_subframe_verbatim(s, ch);
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1218 } else if(sub->type == FLAC_SUBFRAME_FIXED) {
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1219 output_subframe_fixed(s, ch);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1220 } else if(sub->type == FLAC_SUBFRAME_LPC) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
1221 output_subframe_lpc(s, ch);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1222 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1223 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1224 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1225
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1226 static void output_frame_footer(FlacEncodeContext *s)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1227 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1228 int crc;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1229 flush_put_bits(&s->pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1230 crc = bswap_16(av_crc(av_crc8005, 0, s->pb.buf, put_bits_count(&s->pb)>>3));
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1231 put_bits(&s->pb, 16, crc);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1232 flush_put_bits(&s->pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1233 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1234
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1235 static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1236 int buf_size, void *data)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1237 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1238 int ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1239 FlacEncodeContext *s;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1240 int16_t *samples = data;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1241 int out_bytes;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1242
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1243 s = avctx->priv_data;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1244
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1245 s->blocksize = avctx->frame_size;
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1246 init_frame(s);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1247
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1248 copy_samples(s, samples);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1249
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1250 channel_decorrelation(s);
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1251
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1252 for(ch=0; ch<s->channels; ch++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1253 encode_residual(s, ch);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1254 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1255 init_put_bits(&s->pb, frame, buf_size);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1256 output_frame_header(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1257 output_subframes(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1258 output_frame_footer(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1259 out_bytes = put_bits_count(&s->pb) >> 3;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1260
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1261 if(out_bytes > s->max_framesize || out_bytes >= buf_size) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1262 /* frame too large. use verbatim mode */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1263 for(ch=0; ch<s->channels; ch++) {
3365
84f29207af3a flacenc - rice param search patch by (Justin Ruggles jruggle earthlink net
michael
parents: 3358
diff changeset
1264 encode_residual_v(s, ch);
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1265 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1266 init_put_bits(&s->pb, frame, buf_size);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1267 output_frame_header(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1268 output_subframes(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1269 output_frame_footer(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1270 out_bytes = put_bits_count(&s->pb) >> 3;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1271
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1272 if(out_bytes > s->max_framesize || out_bytes >= buf_size) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1273 /* still too large. must be an error. */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1274 av_log(avctx, AV_LOG_ERROR, "error encoding frame\n");
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1275 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1276 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1277 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1278
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1279 s->frame_count++;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1280 return out_bytes;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1281 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1282
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1283 static int flac_encode_close(AVCodecContext *avctx)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1284 {
3358
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1285 av_freep(&avctx->extradata);
4ae69b5b596b stereo decorrelation support by (Justin Ruggles jruggle earthlink net>)
michael
parents: 3357
diff changeset
1286 avctx->extradata_size = 0;
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1287 av_freep(&avctx->coded_frame);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1288 return 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1289 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1290
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1291 AVCodec flac_encoder = {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1292 "flac",
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1293 CODEC_TYPE_AUDIO,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1294 CODEC_ID_FLAC,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1295 sizeof(FlacEncodeContext),
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1296 flac_encode_init,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1297 flac_encode_frame,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1298 flac_encode_close,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1299 NULL,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1300 .capabilities = CODEC_CAP_SMALL_LAST_FRAME,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1301 };