use the sample number for the granulepos
[flac.git] / src / flac / encode.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001,2002  Josh Coalson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18
19 #if defined _WIN32 && !defined __CYGWIN__
20 /* where MSVC puts unlink() */
21 # include <io.h>
22 #else
23 # include <unistd.h>
24 #endif
25 #include <math.h> /* for floor() */
26 #include <stdio.h> /* for FILE et al. */
27 #include <stdlib.h> /* for malloc */
28 #include <string.h> /* for strcmp() */
29 #include "FLAC/all.h"
30 #include "encode.h"
31 #include "file.h"
32 #ifdef FLAC__HAS_OGG
33 #include "ogg/ogg.h"
34 #endif
35
36 #ifdef min
37 #undef min
38 #endif
39 #define min(x,y) ((x)<(y)?(x):(y))
40
41 /* this MUST be >= 588 so that sector aligning can take place with one read */
42 #define CHUNK_OF_SAMPLES 2048
43
44 typedef enum {
45         FLAC__VERIFY_OK,
46         FLAC__VERIFY_FAILED_IN_FRAME,
47         FLAC__VERIFY_FAILED_IN_METADATA
48 } verify_code;
49
50 static const char *verify_code_string[] = {
51         "FLAC__VERIFY_OK",
52         "FLAC__VERIFY_FAILED_IN_FRAME",
53         "FLAC__VERIFY_FAILED_IN_METADATA"
54 };
55
56 typedef struct {
57         FLAC__int32 *original[FLAC__MAX_CHANNELS];
58         unsigned size; /* of each original[] in samples */
59         unsigned tail; /* in wide samples */
60         const FLAC__byte *encoded_signal;
61         unsigned encoded_signal_capacity;
62         unsigned encoded_bytes;
63         FLAC__bool into_frames;
64         verify_code result;
65         FLAC__StreamDecoder *decoder;
66 } verify_fifo_struct;
67
68 #ifdef FLAC__HAS_OGG
69 typedef struct {
70         ogg_stream_state os;
71         ogg_page og;
72 } ogg_info_struct;
73 #endif
74
75 typedef struct {
76         const char *inbasefilename;
77         FILE *fout;
78         const char *outfilename;
79         FLAC__StreamEncoder *encoder;
80         FLAC__bool verify;
81         FLAC__bool verbose;
82         FLAC__uint64 unencoded_size;
83         FLAC__uint64 total_samples_to_encode;
84         FLAC__uint64 bytes_written;
85         FLAC__uint64 samples_written;
86         FLAC__uint64 stream_offset; /* i.e. number of bytes before the first byte of the the first frame's header */
87         unsigned current_frame;
88         verify_fifo_struct verify_fifo;
89         FLAC__StreamMetaData_SeekTable seek_table;
90         unsigned first_seek_point_to_check;
91 #ifdef FLAC__HAS_OGG
92         FLAC__bool use_ogg;
93         ogg_info_struct ogg;
94 #endif
95 } encoder_wrapper_struct;
96
97 static FLAC__bool is_big_endian_host;
98
99 static unsigned char ucbuffer[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__MAX_BITS_PER_SAMPLE+7)/8)];
100 static signed char *scbuffer = (signed char *)ucbuffer;
101 static FLAC__uint16 *usbuffer = (FLAC__uint16 *)ucbuffer;
102 static FLAC__int16 *ssbuffer = (FLAC__int16 *)ucbuffer;
103
104 static FLAC__int32 in[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
105 static FLAC__int32 *input[FLAC__MAX_CHANNELS];
106
107 /* local routines */
108 static FLAC__bool init(encoder_wrapper_struct *encoder_wrapper);
109 static FLAC__bool init_encoder(encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, encoder_wrapper_struct *encoder_wrapper);
110 static FLAC__bool convert_to_seek_table(char *requested_seek_points, int num_requested_seek_points, FLAC__uint64 stream_samples, unsigned blocksize, FLAC__StreamMetaData_SeekTable *seek_table);
111 static void append_point_to_seek_table(FLAC__StreamMetaData_SeekTable *seek_table, FLAC__uint64 sample, FLAC__uint64 stream_samples, FLAC__uint64 blocksize);
112 static int seekpoint_compare(const FLAC__StreamMetaData_SeekPoint *l, const FLAC__StreamMetaData_SeekPoint *r);
113 static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps, encoder_wrapper_struct *encoder_wrapper);
114 static void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 *input[], unsigned channels, unsigned wide_samples);
115 static FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
116 static void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data);
117 static FLAC__StreamDecoderReadStatus verify_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
118 static FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data);
119 static void verify_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
120 static void verify_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
121 static void print_stats(const encoder_wrapper_struct *encoder_wrapper);
122 static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
123 static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
124 static FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val);
125 static FLAC__bool write_big_endian_uint64(FILE *f, FLAC__uint64 val);
126
127 int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
128 {
129         encoder_wrapper_struct encoder_wrapper;
130         FLAC__bool is_unsigned_samples = false;
131         unsigned channels = 0, bps = 0, sample_rate = 0, data_bytes;
132         size_t bytes_per_wide_sample, bytes_read;
133         FLAC__uint16 x;
134         FLAC__uint32 xx;
135         FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
136         unsigned align_remainder = 0;
137         int info_align_carry = -1, info_align_zero = -1;
138
139         FLAC__ASSERT(!options.sector_align || options.common.skip == 0);
140
141         encoder_wrapper.encoder = 0;
142         encoder_wrapper.verify = options.common.verify;
143         encoder_wrapper.verbose = options.common.verbose;
144         encoder_wrapper.bytes_written = 0;
145         encoder_wrapper.samples_written = 0;
146         encoder_wrapper.stream_offset = 0;
147         encoder_wrapper.inbasefilename = flac__file_get_basename(infilename);
148         encoder_wrapper.outfilename = outfilename;
149         encoder_wrapper.seek_table.points = 0;
150         encoder_wrapper.first_seek_point_to_check = 0;
151 #ifdef FLAC__HAS_OGG
152         encoder_wrapper.use_ogg = options.common.use_ogg;
153 #endif
154         (void)infilesize;
155         (void)lookahead;
156         (void)lookahead_length;
157
158         if(0 == strcmp(outfilename, "-")) {
159                 encoder_wrapper.fout = stdout;
160         }
161         else {
162                 if(0 == (encoder_wrapper.fout = fopen(outfilename, "wb"))) {
163                         fprintf(stderr, "%s: ERROR: can't open output file %s\n", encoder_wrapper.inbasefilename, outfilename);
164                         fclose(infile);
165                         return 1;
166                 }
167         }
168
169         if(!init(&encoder_wrapper))
170                 goto wav_abort_;
171
172         /*
173          * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
174          */
175         while(!feof(infile)) {
176                 if(!read_little_endian_uint32(infile, &xx, true, encoder_wrapper.inbasefilename))
177                         goto wav_abort_;
178                 if(feof(infile))
179                         break;
180                 if(xx == 0x20746d66) { /* "fmt " */
181                         if(got_fmt_chunk) {
182                                 fprintf(stderr, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_wrapper.inbasefilename);
183                         }
184                         else {
185                                 /* fmt sub-chunk size */
186                                 if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
187                                         goto wav_abort_;
188                                 if(xx < 16) {
189                                         fprintf(stderr, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_wrapper.inbasefilename, (unsigned)xx);
190                                         goto wav_abort_;
191                                 }
192                                 else if(xx != 16 && xx != 18) {
193                                         fprintf(stderr, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_wrapper.inbasefilename, (unsigned)xx);
194                                 }
195                                 data_bytes = xx;
196                                 /* compression code */
197                                 if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
198                                         goto wav_abort_;
199                                 if(x != 1) {
200                                         fprintf(stderr, "%s: ERROR: unsupported compression type %u\n", encoder_wrapper.inbasefilename, (unsigned)x);
201                                         goto wav_abort_;
202                                 }
203                                 /* number of channels */
204                                 if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
205                                         goto wav_abort_;
206                                 if(x == 0 || x > FLAC__MAX_CHANNELS) {
207                                         fprintf(stderr, "%s: ERROR: unsupported number channels %u\n", encoder_wrapper.inbasefilename, (unsigned)x);
208                                         goto wav_abort_;
209                                 }
210                                 else if(options.sector_align && x != 2) {
211                                         fprintf(stderr, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned)x);
212                                         goto wav_abort_;
213                                 }
214                                 channels = x;
215                                 /* sample rate */
216                                 if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
217                                         goto wav_abort_;
218                                 if(xx == 0 || xx > FLAC__MAX_SAMPLE_RATE) {
219                                         fprintf(stderr, "%s: ERROR: unsupported sample rate %u\n", encoder_wrapper.inbasefilename, (unsigned)xx);
220                                         goto wav_abort_;
221                                 }
222                                 else if(options.sector_align && xx != 44100) {
223                                         fprintf(stderr, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned)xx);
224                                         goto wav_abort_;
225                                 }
226                                 sample_rate = xx;
227                                 /* avg bytes per second (ignored) */
228                                 if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
229                                         goto wav_abort_;
230                                 /* block align (ignored) */
231                                 if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
232                                         goto wav_abort_;
233                                 /* bits per sample */
234                                 if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
235                                         goto wav_abort_;
236                                 if(x != 8 && x != 16 && x != 24) {
237                                         fprintf(stderr, "%s: ERROR: unsupported bits per sample %u\n", encoder_wrapper.inbasefilename, (unsigned)x);
238                                         goto wav_abort_;
239                                 }
240                                 bps = x;
241                                 is_unsigned_samples = (x == 8);
242
243                                 /* skip any extra data in the fmt sub-chunk */
244                                 data_bytes -= 16;
245                                 if(data_bytes > 0) {
246                                         unsigned left, need;
247                                         for(left = data_bytes; left > 0; ) {
248                                                 need = min(left, CHUNK_OF_SAMPLES);
249                                                 if(fread(ucbuffer, 1, need, infile) < need) {
250                                                         fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_wrapper.inbasefilename);
251                                                         goto wav_abort_;
252                                                 }
253                                                 left -= need;
254                                         }
255                                 }
256
257                                 got_fmt_chunk = true;
258                         }
259                 }
260                 else if(xx == 0x61746164) { /* "data" */
261                         if(got_data_chunk) {
262                                 fprintf(stderr, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_wrapper.inbasefilename);
263                         }
264                         else if(!got_fmt_chunk) {
265                                 fprintf(stderr, "%s: ERROR: got data sub-chunk before fmt sub-chunk\n", encoder_wrapper.inbasefilename);
266                                 goto wav_abort_;
267                         }
268                         else {
269                                 /* data size */
270                                 if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
271                                         goto wav_abort_;
272                                 data_bytes = xx;
273
274                                 bytes_per_wide_sample = channels * (bps >> 3);
275
276                                 if(options.common.skip > 0) {
277                                         if(fseek(infile, bytes_per_wide_sample * (unsigned)options.common.skip, SEEK_CUR) < 0) {
278                                                 /* can't seek input, read ahead manually... */
279                                                 unsigned left, need;
280                                                 for(left = (unsigned)options.common.skip; left > 0; ) { /*@@@ WATCHOUT: 4GB limit */
281                                                         need = min(left, CHUNK_OF_SAMPLES);
282                                                         if(fread(ucbuffer, bytes_per_wide_sample, need, infile) < need) {
283                                                                 fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_wrapper.inbasefilename);
284                                                                 goto wav_abort_;
285                                                         }
286                                                         left -= need;
287                                                 }
288                                         }
289                                 }
290
291                                 data_bytes -= (unsigned)options.common.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
292                                 encoder_wrapper.total_samples_to_encode = data_bytes / bytes_per_wide_sample + *options.align_reservoir_samples;
293                                 if(options.sector_align) {
294                                         align_remainder = (unsigned)(encoder_wrapper.total_samples_to_encode % 588);
295                                         if(options.is_last_file)
296                                                 encoder_wrapper.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
297                                         else
298                                                 encoder_wrapper.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
299                                 }
300
301                                 /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
302                                 encoder_wrapper.unencoded_size = encoder_wrapper.total_samples_to_encode * bytes_per_wide_sample + 44;
303
304                                 if(!init_encoder(options.common, channels, bps, sample_rate, &encoder_wrapper))
305                                         goto wav_abort_;
306
307                                 encoder_wrapper.verify_fifo.into_frames = true;
308
309                                 /*
310                                  * first do any samples in the reservoir
311                                  */
312                                 if(options.sector_align && *options.align_reservoir_samples > 0) {
313                                         /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
314                                         append_to_verify_fifo(&encoder_wrapper, options.align_reservoir, channels, *options.align_reservoir_samples);
315
316                                         /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
317                                         if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, options.align_reservoir, *options.align_reservoir_samples)) {
318                                                 fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
319                                                 goto wav_abort_;
320                                         }
321                                 }
322
323                                 /*
324                                  * decrement the data_bytes counter if we need to align the file
325                                  */
326                                 if(options.sector_align) {
327                                         if(options.is_last_file) {
328                                                 *options.align_reservoir_samples = 0;
329                                         }
330                                         else {
331                                                 *options.align_reservoir_samples = align_remainder;
332                                                 data_bytes -= (*options.align_reservoir_samples) * bytes_per_wide_sample;
333                                         }
334                                 }
335
336                                 /*
337                                  * now do from the file
338                                  */
339                                 while(data_bytes > 0) {
340                                         bytes_read = fread(ucbuffer, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
341                                         if(bytes_read == 0) {
342                                                 if(ferror(infile)) {
343                                                         fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
344                                                         goto wav_abort_;
345                                                 }
346                                                 else if(feof(infile)) {
347                                                         fprintf(stderr, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned)encoder_wrapper.total_samples_to_encode, (unsigned)encoder_wrapper.samples_written);
348                                                         data_bytes = 0;
349                                                 }
350                                         }
351                                         else {
352                                                 if(bytes_read % bytes_per_wide_sample != 0) {
353                                                         fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_wrapper.inbasefilename);
354                                                         goto wav_abort_;
355                                                 }
356                                                 else {
357                                                         unsigned wide_samples = bytes_read / bytes_per_wide_sample;
358                                                         format_input(input, wide_samples, false, is_unsigned_samples, channels, bps, &encoder_wrapper);
359
360                                                         /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
361                                                         if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, input, wide_samples)) {
362                                                                 fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
363                                                                 goto wav_abort_;
364                                                         }
365                                                         data_bytes -= bytes_read;
366                                                 }
367                                         }
368                                 }
369
370                                 /*
371                                  * now read unaligned samples into reservoir or pad with zeroes if necessary
372                                  */
373                                 if(options.sector_align) {
374                                         if(options.is_last_file) {
375                                                 unsigned wide_samples = 588 - align_remainder;
376                                                 if(wide_samples < 588) {
377                                                         unsigned channel;
378
379                                                         info_align_zero = wide_samples;
380                                                         data_bytes = wide_samples * bytes_per_wide_sample;
381                                                         for(channel = 0; channel < channels; channel++)
382                                                                 memset(input[channel], 0, data_bytes);
383                                                         /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
384                                                         append_to_verify_fifo(&encoder_wrapper, input, channels, wide_samples);
385
386                                                         /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
387                                                         if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, input, wide_samples)) {
388                                                                 fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
389                                                                 goto wav_abort_;
390                                                         }
391                                                 }
392                                         }
393                                         else {
394                                                 if(*options.align_reservoir_samples > 0) {
395                                                         FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
396                                                         bytes_read = fread(ucbuffer, sizeof(unsigned char), (*options.align_reservoir_samples) * bytes_per_wide_sample, infile);
397                                                         if(bytes_read == 0 && ferror(infile)) {
398                                                                 fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
399                                                                 goto wav_abort_;
400                                                         }
401                                                         else if(bytes_read != (*options.align_reservoir_samples) * bytes_per_wide_sample) {
402                                                                 fprintf(stderr, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned)encoder_wrapper.total_samples_to_encode, (unsigned)encoder_wrapper.samples_written);
403                                                                 data_bytes = 0;
404                                                         }
405                                                         else {
406                                                                 info_align_carry = *options.align_reservoir_samples;
407                                                                 format_input(options.align_reservoir, *options.align_reservoir_samples, false, is_unsigned_samples, channels, bps, &encoder_wrapper);
408                                                         }
409                                                 }
410                                         }
411                                 }
412
413                                 got_data_chunk = true;
414                         }
415                 }
416                 else {
417                         fprintf(stderr, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_wrapper.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
418                         /* sub-chunk size */
419                         if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
420                                 goto wav_abort_;
421                         if(fseek(infile, xx, SEEK_CUR) < 0) {
422                                 /* can't seek input, read ahead manually... */
423                                 unsigned left, need;
424                                 const unsigned chunk = sizeof(ucbuffer);
425                                 for(left = xx; left > 0; ) {
426                                         need = min(left, chunk);
427                                         if(fread(ucbuffer, 1, need, infile) < need) {
428                                                 fprintf(stderr, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_wrapper.inbasefilename);
429                                                 goto wav_abort_;
430                                         }
431                                         left -= need;
432                                 }
433                         }
434                 }
435         }
436
437         if(encoder_wrapper.encoder) {
438                 if(FLAC__stream_encoder_get_state(encoder_wrapper.encoder) == FLAC__STREAM_ENCODER_OK)
439                         FLAC__stream_encoder_finish(encoder_wrapper.encoder);
440                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
441 #ifdef FLAC__HAS_OGG
442                 if(encoder_wrapper.use_ogg)
443                         ogg_stream_clear(&encoder_wrapper.ogg.os);
444 #endif
445         }
446         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0) {
447                 print_stats(&encoder_wrapper);
448                 fprintf(stderr, "\n");
449         }
450         if(0 != encoder_wrapper.seek_table.points)
451                 free(encoder_wrapper.seek_table.points);
452         if(options.common.verify) {
453                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
454                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
455                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
456                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
457                         return 1;
458                 }
459         }
460         if(info_align_carry >= 0)
461                 fprintf(stderr, "%s: INFO: sector alignment causing %d samples to be carried over\n", encoder_wrapper.inbasefilename, info_align_carry);
462         if(info_align_zero >= 0)
463                 fprintf(stderr, "%s: INFO: sector alignment causing %d zero samples to be appended\n", encoder_wrapper.inbasefilename, info_align_zero);
464         if(infile != stdin)
465                 fclose(infile);
466         return 0;
467 wav_abort_:
468         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0)
469                 fprintf(stderr, "\n");
470         if(encoder_wrapper.encoder) {
471                 if(FLAC__stream_encoder_get_state(encoder_wrapper.encoder) == FLAC__STREAM_ENCODER_OK)
472                         FLAC__stream_encoder_finish(encoder_wrapper.encoder);
473                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
474 #ifdef FLAC__HAS_OGG
475                 if(encoder_wrapper.use_ogg)
476                         ogg_stream_clear(&encoder_wrapper.ogg.os);
477 #endif
478         }
479         if(0 != encoder_wrapper.seek_table.points)
480                 free(encoder_wrapper.seek_table.points);
481         if(options.common.verify) {
482                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
483                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
484                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
485                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
486                         return 1;
487                 }
488         }
489         if(infile != stdin)
490                 fclose(infile);
491         unlink(outfilename);
492         return 1;
493 }
494
495 int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
496 {
497         encoder_wrapper_struct encoder_wrapper;
498         size_t bytes_read;
499         const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
500
501         encoder_wrapper.encoder = 0;
502         encoder_wrapper.verify = options.common.verify;
503         encoder_wrapper.verbose = options.common.verbose;
504         encoder_wrapper.bytes_written = 0;
505         encoder_wrapper.samples_written = 0;
506         encoder_wrapper.stream_offset = 0;
507         encoder_wrapper.inbasefilename = flac__file_get_basename(infilename);
508         encoder_wrapper.outfilename = outfilename;
509         encoder_wrapper.seek_table.points = 0;
510         encoder_wrapper.first_seek_point_to_check = 0;
511 #ifdef FLAC__HAS_OGG
512         encoder_wrapper.use_ogg = options.common.use_ogg;
513 #endif
514
515         if(0 == strcmp(outfilename, "-")) {
516                 encoder_wrapper.fout = stdout;
517         }
518         else {
519                 if(0 == (encoder_wrapper.fout = fopen(outfilename, "wb"))) {
520                         fprintf(stderr, "ERROR: can't open output file %s\n", outfilename);
521                         fclose(infile);
522                         return 1;
523                 }
524         }
525
526         if(!init(&encoder_wrapper))
527                 goto raw_abort_;
528
529         /* get the file length */
530         if(infilesize < 0) {
531                 encoder_wrapper.total_samples_to_encode = encoder_wrapper.unencoded_size = 0;
532         }
533         else {
534                 encoder_wrapper.total_samples_to_encode = (unsigned)infilesize / bytes_per_wide_sample - options.common.skip;
535                 encoder_wrapper.unencoded_size = encoder_wrapper.total_samples_to_encode * bytes_per_wide_sample;
536         }
537
538         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode <= 0)
539                 fprintf(stderr, "(No runtime statistics possible; please wait for encoding to finish...)\n");
540
541         if(options.common.skip > 0) {
542                 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)options.common.skip;
543                 if(skip_bytes > lookahead_length) {
544                         skip_bytes -= lookahead_length;
545                         lookahead_length = 0;
546                         if(fseek(infile, (long)skip_bytes, SEEK_CUR) < 0) {
547                                 /* can't seek input, read ahead manually... */
548                                 unsigned left, need;
549                                 const unsigned chunk = sizeof(ucbuffer);
550                                 for(left = skip_bytes; left > 0; ) {
551                                         need = min(left, chunk);
552                                         if(fread(ucbuffer, 1, need, infile) < need) {
553                                                 fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_wrapper.inbasefilename);
554                                                 goto raw_abort_;
555                                         }
556                                         left -= need;
557                                 }
558                         }
559                 }
560                 else {
561                         lookahead += skip_bytes;
562                         lookahead_length -= skip_bytes;
563                 }
564         }
565
566         if(!init_encoder(options.common, options.channels, options.bps, options.sample_rate, &encoder_wrapper))
567                 goto raw_abort_;
568
569         encoder_wrapper.verify_fifo.into_frames = true;
570
571         while(!feof(infile)) {
572                 if(lookahead_length > 0) {
573                         FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
574                         memcpy(ucbuffer, lookahead, lookahead_length);
575                         bytes_read = fread(ucbuffer+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
576                         if(ferror(infile)) {
577                                 fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
578                                 goto raw_abort_;
579                         }
580                         lookahead_length = 0;
581                 }
582                 else
583                         bytes_read = fread(ucbuffer, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
584
585                 if(bytes_read == 0) {
586                         if(ferror(infile)) {
587                                 fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
588                                 goto raw_abort_;
589                         }
590                 }
591                 else if(bytes_read % bytes_per_wide_sample != 0) {
592                         fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_wrapper.inbasefilename);
593                         goto raw_abort_;
594                 }
595                 else {
596                         unsigned wide_samples = bytes_read / bytes_per_wide_sample;
597                         format_input(input, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps, &encoder_wrapper);
598
599                         /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
600                         if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, input, wide_samples)) {
601                                 fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
602                                 goto raw_abort_;
603                         }
604                 }
605         }
606
607         if(encoder_wrapper.encoder) {
608                 if(FLAC__stream_encoder_get_state(encoder_wrapper.encoder) == FLAC__STREAM_ENCODER_OK)
609                         FLAC__stream_encoder_finish(encoder_wrapper.encoder);
610                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
611 #ifdef FLAC__HAS_OGG
612                 if(encoder_wrapper.use_ogg)
613                         ogg_stream_clear(&encoder_wrapper.ogg.os);
614 #endif
615         }
616         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0) {
617                 print_stats(&encoder_wrapper);
618                 fprintf(stderr, "\n");
619         }
620         if(0 != encoder_wrapper.seek_table.points)
621                 free(encoder_wrapper.seek_table.points);
622         if(options.common.verify) {
623                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
624                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
625                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
626                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
627                         return 1;
628                 }
629         }
630         if(infile != stdin)
631                 fclose(infile);
632         return 0;
633 raw_abort_:
634         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0)
635                 fprintf(stderr, "\n");
636         if(encoder_wrapper.encoder) {
637                 if(FLAC__stream_encoder_get_state(encoder_wrapper.encoder) == FLAC__STREAM_ENCODER_OK)
638                         FLAC__stream_encoder_finish(encoder_wrapper.encoder);
639                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
640 #ifdef FLAC__HAS_OGG
641                 if(encoder_wrapper.use_ogg)
642                         ogg_stream_clear(&encoder_wrapper.ogg.os);
643 #endif
644         }
645         if(0 != encoder_wrapper.seek_table.points)
646                 free(encoder_wrapper.seek_table.points);
647         if(options.common.verify) {
648                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
649                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
650                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
651                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
652                         return 1;
653                 }
654         }
655         if(infile != stdin)
656                 fclose(infile);
657         unlink(outfilename);
658         return 1;
659 }
660
661 FLAC__bool init(encoder_wrapper_struct *encoder_wrapper)
662 {
663         unsigned i;
664         FLAC__uint32 test = 1;
665
666         is_big_endian_host = (*((FLAC__byte*)(&test)))? false : true;
667
668         for(i = 0; i < FLAC__MAX_CHANNELS; i++)
669                 input[i] = &(in[i][0]);
670
671         encoder_wrapper->encoder = FLAC__stream_encoder_new();
672         if(0 == encoder_wrapper->encoder) {
673                 fprintf(stderr, "%s: ERROR creating the encoder instance\n", encoder_wrapper->inbasefilename);
674                 return false;
675         }
676
677 #ifdef FLAC__HAS_OGG
678         if(encoder_wrapper->use_ogg) {
679                 if(ogg_stream_init(&encoder_wrapper->ogg.os, 0) != 0) {
680                         fprintf(stderr, "%s: ERROR initializing the Ogg stream\n", encoder_wrapper->inbasefilename);
681                         FLAC__stream_encoder_delete(encoder_wrapper->encoder);
682                         return false;
683                 }
684         }
685 #endif
686
687         return true;
688 }
689
690 FLAC__bool init_encoder(encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, encoder_wrapper_struct *encoder_wrapper)
691 {
692         unsigned i;
693
694         if(channels != 2)
695                 options.do_mid_side = options.loose_mid_side = false;
696
697         if(encoder_wrapper->verify) {
698                 /* set up the fifo which will hold the original signal to compare against */
699                 encoder_wrapper->verify_fifo.size = options.blocksize + CHUNK_OF_SAMPLES;
700                 for(i = 0; i < channels; i++) {
701                         if(0 == (encoder_wrapper->verify_fifo.original[i] = (FLAC__int32*)malloc(sizeof(FLAC__int32) * encoder_wrapper->verify_fifo.size))) {
702                                 fprintf(stderr, "%s: ERROR allocating verify buffers\n", encoder_wrapper->inbasefilename);
703                                 return false;
704                         }
705                 }
706                 encoder_wrapper->verify_fifo.tail = 0;
707                 encoder_wrapper->verify_fifo.into_frames = false;
708                 encoder_wrapper->verify_fifo.result = FLAC__VERIFY_OK;
709
710                 /* set up a stream decoder for verification */
711                 encoder_wrapper->verify_fifo.decoder = FLAC__stream_decoder_new();
712                 if(0 == encoder_wrapper->verify_fifo.decoder) {
713                         fprintf(stderr, "%s: ERROR creating the verify decoder instance\n", encoder_wrapper->inbasefilename);
714                         return false;
715                 }
716                 FLAC__stream_decoder_set_read_callback(encoder_wrapper->verify_fifo.decoder, verify_read_callback);
717                 FLAC__stream_decoder_set_write_callback(encoder_wrapper->verify_fifo.decoder, verify_write_callback);
718                 FLAC__stream_decoder_set_metadata_callback(encoder_wrapper->verify_fifo.decoder, verify_metadata_callback);
719                 FLAC__stream_decoder_set_error_callback(encoder_wrapper->verify_fifo.decoder, verify_error_callback);
720                 FLAC__stream_decoder_set_client_data(encoder_wrapper->verify_fifo.decoder, encoder_wrapper);
721                 if(FLAC__stream_decoder_init(encoder_wrapper->verify_fifo.decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) {
722                         fprintf(stderr, "%s: ERROR initializing decoder, state = %d:%s\n", encoder_wrapper->inbasefilename, FLAC__stream_decoder_get_state(encoder_wrapper->verify_fifo.decoder), FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(encoder_wrapper->verify_fifo.decoder)]);
723                         return false;
724                 }
725         }
726
727         if(!convert_to_seek_table(options.requested_seek_points, options.num_requested_seek_points, encoder_wrapper->total_samples_to_encode, options.blocksize, &encoder_wrapper->seek_table)) {
728                 fprintf(stderr, "%s: ERROR allocating seek table\n", encoder_wrapper->inbasefilename);
729                 return false;
730         }
731
732         FLAC__stream_encoder_set_streamable_subset(encoder_wrapper->encoder, !options.lax);
733         FLAC__stream_encoder_set_do_mid_side_stereo(encoder_wrapper->encoder, options.do_mid_side);
734         FLAC__stream_encoder_set_loose_mid_side_stereo(encoder_wrapper->encoder, options.loose_mid_side);
735         FLAC__stream_encoder_set_channels(encoder_wrapper->encoder, channels);
736         FLAC__stream_encoder_set_bits_per_sample(encoder_wrapper->encoder, bps);
737         FLAC__stream_encoder_set_sample_rate(encoder_wrapper->encoder, sample_rate);
738         FLAC__stream_encoder_set_blocksize(encoder_wrapper->encoder, options.blocksize);
739         FLAC__stream_encoder_set_max_lpc_order(encoder_wrapper->encoder, options.max_lpc_order);
740         FLAC__stream_encoder_set_qlp_coeff_precision(encoder_wrapper->encoder, options.qlp_coeff_precision);
741         FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder_wrapper->encoder, options.do_qlp_coeff_prec_search);
742         FLAC__stream_encoder_set_do_escape_coding(encoder_wrapper->encoder, options.do_escape_coding);
743         FLAC__stream_encoder_set_do_exhaustive_model_search(encoder_wrapper->encoder, options.do_exhaustive_model_search);
744         FLAC__stream_encoder_set_min_residual_partition_order(encoder_wrapper->encoder, options.min_residual_partition_order);
745         FLAC__stream_encoder_set_max_residual_partition_order(encoder_wrapper->encoder, options.max_residual_partition_order);
746         FLAC__stream_encoder_set_rice_parameter_search_dist(encoder_wrapper->encoder, options.rice_parameter_search_dist);
747         FLAC__stream_encoder_set_total_samples_estimate(encoder_wrapper->encoder, encoder_wrapper->total_samples_to_encode);
748         FLAC__stream_encoder_set_seek_table(encoder_wrapper->encoder, (encoder_wrapper->seek_table.num_points > 0)? &encoder_wrapper->seek_table : 0);
749         FLAC__stream_encoder_set_padding(encoder_wrapper->encoder, options.padding);
750         FLAC__stream_encoder_set_last_metadata_is_last(encoder_wrapper->encoder, true);
751         FLAC__stream_encoder_set_write_callback(encoder_wrapper->encoder, write_callback);
752         FLAC__stream_encoder_set_metadata_callback(encoder_wrapper->encoder, metadata_callback);
753         FLAC__stream_encoder_set_client_data(encoder_wrapper->encoder, encoder_wrapper);
754
755         if(FLAC__stream_encoder_init(encoder_wrapper->encoder) != FLAC__STREAM_ENCODER_OK) {
756                 fprintf(stderr, "%s: ERROR initializing encoder, state = %d:%s\n", encoder_wrapper->inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper->encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper->encoder)]);
757                 return false;
758         }
759
760         /* the above call writes all the metadata, so we save the stream offset now */
761         encoder_wrapper->stream_offset = encoder_wrapper->bytes_written;
762
763         return true;
764 }
765
766 FLAC__bool convert_to_seek_table(char *requested_seek_points, int num_requested_seek_points, FLAC__uint64 stream_samples, unsigned blocksize, FLAC__StreamMetaData_SeekTable *seek_table)
767 {
768         unsigned i, j, real_points, placeholders;
769         char *pt = requested_seek_points, *q;
770         FLAC__bool first;
771
772         seek_table->num_points = 0;
773
774         if(num_requested_seek_points == 0)
775                 return true;
776
777         if(num_requested_seek_points < 0) {
778                 strcpy(requested_seek_points, "100x<");
779                 num_requested_seek_points = 1;
780         }
781
782         /* first count how many individual seek point we may need */
783         real_points = placeholders = 0;
784         for(i = 0; i < (unsigned)num_requested_seek_points; i++) {
785                 q = strchr(pt, '<');
786                 FLAC__ASSERT(0 != q);
787                 *q = '\0';
788
789                 if(0 == strcmp(pt, "X")) { /* -S X */
790                         placeholders++;
791                 }
792                 else if(pt[strlen(pt)-1] == 'x') { /* -S #x */
793                         if(stream_samples > 0) /* we can only do these if we know the number of samples to encode up front */
794                                 real_points += (unsigned)atoi(pt);
795                 }
796                 else { /* -S # */
797                         real_points++;
798                 }
799                 *q++ = '<';
800
801                 pt = q;
802         }
803         pt = requested_seek_points;
804
805         /* make some space */
806         if(0 == (seek_table->points = (FLAC__StreamMetaData_SeekPoint*)malloc(sizeof(FLAC__StreamMetaData_SeekPoint) * (real_points+placeholders))))
807                 return false;
808
809         /* initialize the seek_table.  we set frame_samples to zero to signify the points have not yet been hit by a frame write yet. */
810         for(i = 0; i < real_points+placeholders; i++) {
811                 seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
812                 seek_table->points[i].stream_offset = 0;
813                 seek_table->points[i].frame_samples = 0;
814         }
815
816         for(i = 0; i < (unsigned)num_requested_seek_points; i++) {
817                 q = strchr(pt, '<');
818                 FLAC__ASSERT(0 != q);
819                 *q++ = '\0';
820
821                 if(0 == strcmp(pt, "X")) { /* -S X */
822                         ; /* we append placeholders later */
823                 }
824                 else if(pt[strlen(pt)-1] == 'x') { /* -S #x */
825                         if(stream_samples > 0) { /* we can only do these if we know the number of samples to encode up front */
826                                 unsigned j, n;
827                                 n = (unsigned)atoi(pt);
828                                 for(j = 0; j < n; j++)
829                                         append_point_to_seek_table(seek_table, stream_samples * (FLAC__uint64)j / (FLAC__uint64)n, stream_samples, blocksize);
830                         }
831                 }
832                 else { /* -S # */
833                         append_point_to_seek_table(seek_table, (FLAC__uint64)atoi(pt), stream_samples, blocksize);
834                 }
835
836                 pt = q;
837         }
838
839         /* sort the seekpoints */
840         qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetaData_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare);
841
842         /* uniqify the seekpoints */
843         first = true;
844         for(i = j = 0; i < seek_table->num_points; i++) {
845                 if(!first) {
846                         if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
847                                 continue;
848                 }
849                 first = false;
850                 seek_table->points[j++] = seek_table->points[i];
851         }
852         seek_table->num_points = j;
853
854         /* append placeholders */
855         for(i = 0, j = seek_table->num_points; i < placeholders; i++, j++)
856                 seek_table->points[j].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
857         seek_table->num_points += placeholders;
858
859         return true;
860 }
861
862 void append_point_to_seek_table(FLAC__StreamMetaData_SeekTable *seek_table, FLAC__uint64 sample, FLAC__uint64 stream_samples, FLAC__uint64 blocksize)
863 {
864         const FLAC__uint64 target_sample = (sample / blocksize) * blocksize;
865
866         if(stream_samples == 0 || target_sample < stream_samples)
867                 seek_table->points[seek_table->num_points++].sample_number = target_sample;
868 }
869
870 int seekpoint_compare(const FLAC__StreamMetaData_SeekPoint *l, const FLAC__StreamMetaData_SeekPoint *r)
871 {
872         /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
873         if(l->sample_number == r->sample_number)
874                 return 0;
875         else if(l->sample_number < r->sample_number)
876                 return -1;
877         else
878                 return 1;
879 }
880
881 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps, encoder_wrapper_struct *encoder_wrapper)
882 {
883         unsigned wide_sample, sample, channel, byte;
884
885         if(bps == 8) {
886                 if(is_unsigned_samples) {
887                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
888                                 for(channel = 0; channel < channels; channel++, sample++)
889                                         dest[channel][wide_sample] = (FLAC__int32)ucbuffer[sample] - 0x80;
890                 }
891                 else {
892                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
893                                 for(channel = 0; channel < channels; channel++, sample++)
894                                         dest[channel][wide_sample] = (FLAC__int32)scbuffer[sample];
895                 }
896         }
897         else if(bps == 16) {
898                 if(is_big_endian != is_big_endian_host) {
899                         unsigned char tmp;
900                         const unsigned bytes = wide_samples * channels * (bps >> 3);
901                         for(byte = 0; byte < bytes; byte += 2) {
902                                 tmp = ucbuffer[byte];
903                                 ucbuffer[byte] = ucbuffer[byte+1];
904                                 ucbuffer[byte+1] = tmp;
905                         }
906                 }
907                 if(is_unsigned_samples) {
908                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
909                                 for(channel = 0; channel < channels; channel++, sample++)
910                                         dest[channel][wide_sample] = (FLAC__int32)usbuffer[sample] - 0x8000;
911                 }
912                 else {
913                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
914                                 for(channel = 0; channel < channels; channel++, sample++)
915                                         dest[channel][wide_sample] = (FLAC__int32)ssbuffer[sample];
916                 }
917         }
918         else if(bps == 24) {
919                 if(!is_big_endian) {
920                         unsigned char tmp;
921                         const unsigned bytes = wide_samples * channels * (bps >> 3);
922                         for(byte = 0; byte < bytes; byte += 3) {
923                                 tmp = ucbuffer[byte];
924                                 ucbuffer[byte] = ucbuffer[byte+2];
925                                 ucbuffer[byte+2] = tmp;
926                         }
927                 }
928                 if(is_unsigned_samples) {
929                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
930                                 for(channel = 0; channel < channels; channel++, sample++) {
931                                         dest[channel][wide_sample]  = ucbuffer[byte++]; dest[channel][wide_sample] <<= 8;
932                                         dest[channel][wide_sample] |= ucbuffer[byte++]; dest[channel][wide_sample] <<= 8;
933                                         dest[channel][wide_sample] |= ucbuffer[byte++];
934                                         dest[channel][wide_sample] -= 0x800000;
935                                 }
936                 }
937                 else {
938                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
939                                 for(channel = 0; channel < channels; channel++, sample++) {
940                                         dest[channel][wide_sample]  = scbuffer[byte++]; dest[channel][wide_sample] <<= 8;
941                                         dest[channel][wide_sample] |= ucbuffer[byte++]; dest[channel][wide_sample] <<= 8;
942                                         dest[channel][wide_sample] |= ucbuffer[byte++];
943                                 }
944                 }
945         }
946         else {
947                 FLAC__ASSERT(0);
948         }
949
950         /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
951         append_to_verify_fifo(encoder_wrapper, dest, channels, wide_samples);
952 }
953
954 void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 *src[], unsigned channels, unsigned wide_samples)
955 {
956         if(encoder_wrapper->verify) {
957                 unsigned channel;
958                 for(channel = 0; channel < channels; channel++)
959                         memcpy(&encoder_wrapper->verify_fifo.original[channel][encoder_wrapper->verify_fifo.tail], src[channel], sizeof(FLAC__int32) * wide_samples);
960                 encoder_wrapper->verify_fifo.tail += wide_samples;
961                 FLAC__ASSERT(encoder_wrapper->verify_fifo.tail <= encoder_wrapper->verify_fifo.size);
962         }
963 }
964
965 FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
966 {
967         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
968         const unsigned mask = (FLAC__stream_encoder_get_do_exhaustive_model_search(encoder) || FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder))? 0x1f : 0x7f;
969
970         /* mark the current seek point if hit (if stream_offset == 0 that means we're still writing metadata and haven't hit the first frame yet) */
971         if(encoder_wrapper->stream_offset > 0 && encoder_wrapper->seek_table.num_points > 0) {
972                 FLAC__uint64 current_sample = (FLAC__uint64)current_frame * (FLAC__uint64)FLAC__stream_encoder_get_blocksize(encoder), test_sample;
973                 unsigned i;
974                 for(i = encoder_wrapper->first_seek_point_to_check; i < encoder_wrapper->seek_table.num_points; i++) {
975                         test_sample = encoder_wrapper->seek_table.points[i].sample_number;
976                         if(test_sample > current_sample) {
977                                 break;
978                         }
979                         else if(test_sample == current_sample) {
980                                 encoder_wrapper->seek_table.points[i].stream_offset = encoder_wrapper->bytes_written - encoder_wrapper->stream_offset;
981                                 encoder_wrapper->seek_table.points[i].frame_samples = FLAC__stream_encoder_get_blocksize(encoder);
982                                 encoder_wrapper->first_seek_point_to_check++;
983                                 break;
984                         }
985                         else {
986                                 encoder_wrapper->first_seek_point_to_check++;
987                         }
988                 }
989         }
990
991         encoder_wrapper->bytes_written += bytes;
992         encoder_wrapper->samples_written += samples;
993         encoder_wrapper->current_frame = current_frame;
994
995         if(samples && encoder_wrapper->verbose && encoder_wrapper->total_samples_to_encode > 0 && !(current_frame & mask))
996                 print_stats(encoder_wrapper);
997
998         if(encoder_wrapper->verify) {
999                 encoder_wrapper->verify_fifo.encoded_signal = buffer;
1000                 encoder_wrapper->verify_fifo.encoded_bytes = bytes;
1001                 if(encoder_wrapper->verify_fifo.into_frames) {
1002                         if(!FLAC__stream_decoder_process_one_frame(encoder_wrapper->verify_fifo.decoder)) {
1003                                 encoder_wrapper->verify_fifo.result = FLAC__VERIFY_FAILED_IN_FRAME;
1004                                 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
1005                         }
1006                 }
1007                 else {
1008                         if(!FLAC__stream_decoder_process_metadata(encoder_wrapper->verify_fifo.decoder)) {
1009                                 encoder_wrapper->verify_fifo.result = FLAC__VERIFY_FAILED_IN_METADATA;
1010                                 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
1011                         }
1012                 }
1013         }
1014
1015 #ifdef FLAC__HAS_OGG
1016         if(encoder_wrapper->use_ogg) {
1017                 ogg_packet op;
1018
1019                 memset(&op, 0, sizeof(op));
1020                 op.packet = (unsigned char *)buffer;
1021                 op.granulepos = encoder_wrapper->bytes_written - 1;
1022                 op.packetno = encoder_wrapper->current_frame;
1023                 op.bytes = bytes;
1024
1025                 if (encoder_wrapper->bytes_written == bytes)
1026                         op.b_o_s = 1;
1027
1028                 if (encoder_wrapper->total_samples_to_encode == encoder_wrapper->samples_written)
1029                         op.e_o_s = 1;
1030
1031                 ogg_stream_packetin(&encoder_wrapper->ogg.os, &op);
1032
1033                 while(ogg_stream_pageout(&encoder_wrapper->ogg.os, &encoder_wrapper->ogg.og) != 0) {
1034                         int written;
1035                         written = fwrite(encoder_wrapper->ogg.og.header, 1, encoder_wrapper->ogg.og.header_len, encoder_wrapper->fout);
1036                         if (written != encoder_wrapper->ogg.og.header_len)
1037                                 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
1038
1039                         written = fwrite(encoder_wrapper->ogg.og.body, 1, encoder_wrapper->ogg.og.body_len, encoder_wrapper->fout);
1040                         if (written != encoder_wrapper->ogg.og.body_len)
1041                                 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
1042                 }
1043
1044                 return FLAC__STREAM_ENCODER_WRITE_OK;
1045         }
1046         else
1047 #endif
1048         {
1049                 if(fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_wrapper->fout) == bytes)
1050                         return FLAC__STREAM_ENCODER_WRITE_OK;
1051                 else
1052                         return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
1053         }
1054 }
1055
1056 void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data)
1057 {
1058         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1059         FLAC__byte b;
1060         FILE *f;
1061         const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
1062         const unsigned min_framesize = metadata->data.stream_info.min_framesize;
1063         const unsigned max_framesize = metadata->data.stream_info.max_framesize;
1064
1065         FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
1066
1067         /*
1068          * If we are writing to an ogg stream, there is no need to go back
1069          * and update the STREAMINFO or SEEKTABLE blocks; the values we would
1070          * update are not necessary with Ogg as the transport.  We can't do
1071          * it reliably anyway without knowing the Ogg structure.
1072          */
1073 #ifdef FLAC__HAS_OGG
1074         if(encoder_wrapper->use_ogg)
1075                 return;
1076 #endif
1077
1078         /*
1079          * we get called by the encoder when the encoding process has
1080          * finished so that we can update the STREAMINFO and SEEKTABLE
1081          * blocks.
1082          */
1083
1084         (void)encoder; /* silence compiler warning about unused parameter */
1085
1086         if(encoder_wrapper->fout != stdout) {
1087                 fclose(encoder_wrapper->fout);
1088                 if(0 == (f = fopen(encoder_wrapper->outfilename, "r+b")))
1089                         return;
1090         }
1091         else
1092                 f = stdout;
1093
1094         /* all this is based on intimate knowledge of the stream header
1095          * layout, but a change to the header format that would break this
1096          * would also break all streams encoded in the previous format.
1097          */
1098
1099         if(-1 == fseek(f, 26, SEEK_SET)) goto end_;
1100         fwrite(metadata->data.stream_info.md5sum, 1, 16, f);
1101
1102 samples_:
1103         /* if we get this far we know we can seek so no need to check the
1104          * return value from fseek()
1105          */
1106         fseek(f, 21, SEEK_SET);
1107         if(fread(&b, 1, 1, f) != 1) goto framesize_;
1108         fseek(f, 21, SEEK_SET);
1109         b = (b & 0xf0) | (FLAC__byte)((samples >> 32) & 0x0F);
1110         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1111         b = (FLAC__byte)((samples >> 24) & 0xFF);
1112         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1113         b = (FLAC__byte)((samples >> 16) & 0xFF);
1114         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1115         b = (FLAC__byte)((samples >> 8) & 0xFF);
1116         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1117         b = (FLAC__byte)(samples & 0xFF);
1118         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1119
1120 framesize_:
1121         fseek(f, 12, SEEK_SET);
1122         b = (FLAC__byte)((min_framesize >> 16) & 0xFF);
1123         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1124         b = (FLAC__byte)((min_framesize >> 8) & 0xFF);
1125         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1126         b = (FLAC__byte)(min_framesize & 0xFF);
1127         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1128         b = (FLAC__byte)((max_framesize >> 16) & 0xFF);
1129         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1130         b = (FLAC__byte)((max_framesize >> 8) & 0xFF);
1131         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1132         b = (FLAC__byte)(max_framesize & 0xFF);
1133         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1134
1135 seektable_:
1136         if(encoder_wrapper->seek_table.num_points > 0) {
1137                 long pos;
1138                 unsigned i;
1139
1140                 /* convert any unused seek points to placeholders */
1141                 for(i = 0; i < encoder_wrapper->seek_table.num_points; i++) {
1142                         if(encoder_wrapper->seek_table.points[i].sample_number == FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER)
1143                                 break;
1144                         else if(encoder_wrapper->seek_table.points[i].frame_samples == 0)
1145                                 encoder_wrapper->seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
1146                 }
1147
1148                 /* the offset of the seek table data 'pos' should be after then stream sync and STREAMINFO block and SEEKTABLE header */
1149                 pos = (FLAC__STREAM_SYNC_LEN + FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
1150                 pos += metadata->length;
1151                 pos += (FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
1152                 fseek(f, pos, SEEK_SET);
1153                 for(i = 0; i < encoder_wrapper->seek_table.num_points; i++) {
1154                         if(!write_big_endian_uint64(f, encoder_wrapper->seek_table.points[i].sample_number)) goto end_;
1155                         if(!write_big_endian_uint64(f, encoder_wrapper->seek_table.points[i].stream_offset)) goto end_;
1156                         if(!write_big_endian_uint16(f, (FLAC__uint16)encoder_wrapper->seek_table.points[i].frame_samples)) goto end_;
1157                 }
1158         }
1159
1160 end_:
1161         fclose(f);
1162         return;
1163 }
1164
1165 FLAC__StreamDecoderReadStatus verify_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
1166 {
1167         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1168         const unsigned encoded_bytes = encoder_wrapper->verify_fifo.encoded_bytes;
1169         (void)decoder;
1170
1171         if(encoded_bytes <= *bytes) {
1172                 *bytes = encoded_bytes;
1173                 memcpy(buffer, encoder_wrapper->verify_fifo.encoded_signal, *bytes);
1174         }
1175         else {
1176                 memcpy(buffer, encoder_wrapper->verify_fifo.encoded_signal, *bytes);
1177                 encoder_wrapper->verify_fifo.encoded_signal += *bytes;
1178                 encoder_wrapper->verify_fifo.encoded_bytes -= *bytes;
1179         }
1180
1181         return FLAC__STREAM_DECODER_READ_CONTINUE;
1182 }
1183
1184 FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)
1185 {
1186         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1187         unsigned channel, l, r;
1188         const unsigned channels = FLAC__stream_decoder_get_channels(decoder);
1189         const unsigned bytes_per_block = sizeof(FLAC__int32) * FLAC__stream_decoder_get_blocksize(decoder);
1190
1191         for(channel = 0; channel < channels; channel++) {
1192                 if(0 != memcmp(buffer[channel], encoder_wrapper->verify_fifo.original[channel], bytes_per_block)) {
1193                         unsigned sample = 0;
1194                         int expect = 0, got = 0;
1195                         fprintf(stderr, "\n%s: ERROR: mismatch in decoded data, verify FAILED!\n", encoder_wrapper->inbasefilename);
1196                         fprintf(stderr, "       Please submit a bug report to\n");
1197                         fprintf(stderr, "           http://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
1198                         fprintf(stderr, "       Make sure to include an email contact in the comment and/or use the\n");
1199                         fprintf(stderr, "       \"Monitor\" feature to monitor the bug status.\n");
1200                         for(l = 0, r = FLAC__stream_decoder_get_blocksize(decoder); l < r; l++) {
1201                                 if(buffer[channel][l] != encoder_wrapper->verify_fifo.original[channel][l]) {
1202                                         sample = l;
1203                                         expect = (int)encoder_wrapper->verify_fifo.original[channel][l];
1204                                         got = (int)buffer[channel][l];
1205                                         break;
1206                                 }
1207                         }
1208                         FLAC__ASSERT(l < r);
1209                         FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
1210                         fprintf(stderr, "       Absolute sample=%u, frame=%u, channel=%u, sample=%u, expected %d, got %d\n", (unsigned)frame->header.number.sample_number + sample, (unsigned)frame->header.number.sample_number / FLAC__stream_decoder_get_blocksize(decoder), channel, sample, expect, got); /*@@@ WATCHOUT: 4GB limit */
1211                         return FLAC__STREAM_DECODER_WRITE_ABORT;
1212                 }
1213         }
1214         /* dequeue the frame from the fifo */
1215         for(channel = 0; channel < channels; channel++) {
1216                 for(l = 0, r = frame->header.blocksize; r < encoder_wrapper->verify_fifo.tail; l++, r++) {
1217                         encoder_wrapper->verify_fifo.original[channel][l] = encoder_wrapper->verify_fifo.original[channel][r];
1218                 }
1219         }
1220         encoder_wrapper->verify_fifo.tail -= frame->header.blocksize;
1221         return FLAC__STREAM_DECODER_WRITE_CONTINUE;
1222 }
1223
1224 void verify_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
1225 {
1226         (void)decoder;
1227         (void)metadata;
1228         (void)client_data;
1229 }
1230
1231 void verify_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
1232 {
1233         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1234         (void)decoder;
1235         fprintf(stderr, "\n%s: ERROR: verification decoder returned error %d:%s\n", encoder_wrapper->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status]);
1236 }
1237
1238 void print_stats(const encoder_wrapper_struct *encoder_wrapper)
1239 {
1240 #if defined _MSC_VER || defined __MINGW32__
1241         /* with VC++ you have to spoon feed it the casting */
1242         const double progress = (double)(FLAC__int64)encoder_wrapper->samples_written / (double)(FLAC__int64)encoder_wrapper->total_samples_to_encode;
1243         const double ratio = (double)(FLAC__int64)encoder_wrapper->bytes_written / ((double)(FLAC__int64)encoder_wrapper->unencoded_size * progress);
1244 #else
1245         const double progress = (double)encoder_wrapper->samples_written / (double)encoder_wrapper->total_samples_to_encode;
1246         const double ratio = (double)encoder_wrapper->bytes_written / ((double)encoder_wrapper->unencoded_size * progress);
1247 #endif
1248
1249         if(encoder_wrapper->samples_written == encoder_wrapper->total_samples_to_encode) {
1250                 fprintf(stderr, "\r%s:%s wrote %u bytes, ratio=%0.3f",
1251                         encoder_wrapper->inbasefilename,
1252                         encoder_wrapper->verify? (encoder_wrapper->verify_fifo.result == FLAC__VERIFY_OK? " Verify OK," : " Verify FAILED!") : "",
1253                         (unsigned)encoder_wrapper->bytes_written,
1254                         ratio
1255                 );
1256         }
1257         else {
1258                 fprintf(stderr, "\r%s: %u%% complete, ratio=%0.3f", encoder_wrapper->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
1259         }
1260 }
1261
1262 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
1263 {
1264         size_t bytes_read = fread(val, 1, 2, f);
1265
1266         if(bytes_read == 0) {
1267                 if(!eof_ok) {
1268                         fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1269                         return false;
1270                 }
1271                 else
1272                         return true;
1273         }
1274         else if(bytes_read < 2) {
1275                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1276                 return false;
1277         }
1278         else {
1279                 if(is_big_endian_host) {
1280                         FLAC__byte tmp, *b = (FLAC__byte*)val;
1281                         tmp = b[1]; b[1] = b[0]; b[0] = tmp;
1282                 }
1283                 return true;
1284         }
1285 }
1286
1287 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
1288 {
1289         size_t bytes_read = fread(val, 1, 4, f);
1290
1291         if(bytes_read == 0) {
1292                 if(!eof_ok) {
1293                         fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1294                         return false;
1295                 }
1296                 else
1297                         return true;
1298         }
1299         else if(bytes_read < 4) {
1300                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1301                 return false;
1302         }
1303         else {
1304                 if(is_big_endian_host) {
1305                         FLAC__byte tmp, *b = (FLAC__byte*)val;
1306                         tmp = b[3]; b[3] = b[0]; b[0] = tmp;
1307                         tmp = b[2]; b[2] = b[1]; b[1] = tmp;
1308                 }
1309                 return true;
1310         }
1311 }
1312
1313 FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val)
1314 {
1315         if(!is_big_endian_host) {
1316                 FLAC__byte *b = (FLAC__byte *)&val, tmp;
1317                 tmp = b[0]; b[0] = b[1]; b[1] = tmp;
1318         }
1319         return fwrite(&val, 1, 2, f) == 2;
1320 }
1321
1322 FLAC__bool write_big_endian_uint64(FILE *f, FLAC__uint64 val)
1323 {
1324         if(!is_big_endian_host) {
1325                 FLAC__byte *b = (FLAC__byte *)&val, tmp;
1326                 tmp = b[0]; b[0] = b[7]; b[7] = tmp;
1327                 tmp = b[1]; b[1] = b[6]; b[6] = tmp;
1328                 tmp = b[2]; b[2] = b[5]; b[5] = tmp;
1329                 tmp = b[3]; b[3] = b[4]; b[4] = tmp;
1330         }
1331         return fwrite(&val, 1, 8, f) == 8;
1332 }