Lines 38-51
Link Here
|
38 |
|
38 |
|
39 |
#if defined(AU_FLAC_DLL) || defined(AU_OGGFLAC_DLL) |
39 |
#if defined(AU_FLAC_DLL) || defined(AU_OGGFLAC_DLL) |
40 |
#include <windows.h> |
40 |
#include <windows.h> |
41 |
#define FLAC__EXPORT_H /* don't include "OggFLAC/export.h" */ |
41 |
#include <FLAC/export.h> /* need export.h to figure out API version from FLAC_API_VERSION_CURRENT */ |
42 |
#define FLAC_API |
42 |
#undef FLAC_API |
43 |
#define OggFLAC__EXPORT_H /* don't include "FLAC/export.h" */ |
43 |
#undef OggFLAC_API |
44 |
#define OggFLAC_API |
|
|
45 |
#endif |
44 |
#endif |
46 |
|
45 |
|
47 |
#include <FLAC/all.h> |
46 |
#include <FLAC/all.h> |
48 |
#ifdef AU_OGGFLAC |
47 |
|
|
|
48 |
/* by LEGACY_FLAC we mean before FLAC 1.1.3 */ |
49 |
/* in FLAC 1.1.3, libOggFLAC is merged into libFLAC and all encoding layers are merged into the stream encoder */ |
50 |
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT < 8 |
51 |
#define LEGACY_FLAC |
52 |
#else |
53 |
#undef LEGACY_FLAC |
54 |
#endif |
55 |
|
56 |
#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) |
49 |
#include <OggFLAC/stream_encoder.h> |
57 |
#include <OggFLAC/stream_encoder.h> |
50 |
#endif |
58 |
#endif |
51 |
|
59 |
|
Lines 100-116
Link Here
|
100 |
unsigned long out_bytes; |
108 |
unsigned long out_bytes; |
101 |
union { |
109 |
union { |
102 |
FLAC__StreamEncoderState flac; |
110 |
FLAC__StreamEncoderState flac; |
|
|
111 |
#ifdef LEGACY_FLAC |
103 |
FLAC__SeekableStreamEncoderState s_flac; |
112 |
FLAC__SeekableStreamEncoderState s_flac; |
104 |
#ifdef AU_OGGFLAC |
113 |
#ifdef AU_OGGFLAC |
105 |
OggFLAC__StreamEncoderState ogg; |
114 |
OggFLAC__StreamEncoderState ogg; |
106 |
#endif |
115 |
#endif |
|
|
116 |
#endif |
107 |
} state; |
117 |
} state; |
108 |
union { |
118 |
union { |
109 |
union { |
119 |
union { |
110 |
FLAC__StreamEncoder *stream; |
120 |
FLAC__StreamEncoder *stream; |
|
|
121 |
#ifdef LEGACY_FLAC |
111 |
FLAC__SeekableStreamEncoder *s_stream; |
122 |
FLAC__SeekableStreamEncoder *s_stream; |
|
|
123 |
#endif |
112 |
} flac; |
124 |
} flac; |
113 |
#ifdef AU_OGGFLAC |
125 |
#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) |
114 |
union { |
126 |
union { |
115 |
OggFLAC__StreamEncoder *stream; |
127 |
OggFLAC__StreamEncoder *stream; |
116 |
} ogg; |
128 |
} ogg; |
Lines 158-164
Link Here
|
158 |
static long serial_number = 0; |
170 |
static long serial_number = 0; |
159 |
FLAC_ctx *flac_ctx = NULL; |
171 |
FLAC_ctx *flac_ctx = NULL; |
160 |
|
172 |
|
161 |
#ifdef AU_OGGFLAC |
173 |
#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) |
162 |
static FLAC__StreamEncoderWriteStatus |
174 |
static FLAC__StreamEncoderWriteStatus |
163 |
ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, |
175 |
ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, |
164 |
const FLAC__byte buffer[], |
176 |
const FLAC__byte buffer[], |
Lines 168-175
Link Here
|
168 |
static FLAC__StreamEncoderWriteStatus |
180 |
static FLAC__StreamEncoderWriteStatus |
169 |
flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, |
181 |
flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, |
170 |
const FLAC__byte buffer[], |
182 |
const FLAC__byte buffer[], |
|
|
183 |
#ifdef LEGACY_FLAC |
171 |
unsigned bytes, unsigned samples, |
184 |
unsigned bytes, unsigned samples, |
|
|
185 |
#else |
186 |
size_t bytes, unsigned samples, |
187 |
#endif |
172 |
unsigned current_frame, void *client_data); |
188 |
unsigned current_frame, void *client_data); |
|
|
189 |
#ifdef LEGACY_FLAC |
173 |
static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, |
190 |
static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, |
174 |
const FLAC__StreamMetadata *metadata, |
191 |
const FLAC__StreamMetadata *metadata, |
175 |
void *client_data); |
192 |
void *client_data); |
Lines 181-186
Link Here
|
181 |
static void flac_seekable_stream_encoder_metadata_callback(const FLAC__SeekableStreamEncoder *encoder, |
198 |
static void flac_seekable_stream_encoder_metadata_callback(const FLAC__SeekableStreamEncoder *encoder, |
182 |
const FLAC__StreamMetadata *metadata, |
199 |
const FLAC__StreamMetadata *metadata, |
183 |
void *client_data); |
200 |
void *client_data); |
|
|
201 |
#endif |
184 |
|
202 |
|
185 |
/* preset */ |
203 |
/* preset */ |
186 |
void flac_set_compression_level(int compression_level) |
204 |
void flac_set_compression_level(int compression_level) |
Lines 281-287
Link Here
|
281 |
#ifdef AU_OGGFLAC |
299 |
#ifdef AU_OGGFLAC |
282 |
void flac_set_option_oggflac(int isogg) |
300 |
void flac_set_option_oggflac(int isogg) |
283 |
{ |
301 |
{ |
|
|
302 |
#ifdef LEGACY_FLAC |
284 |
flac_options.isogg = isogg; |
303 |
flac_options.isogg = isogg; |
|
|
304 |
#else |
305 |
flac_options.isogg = (FLAC_API_SUPPORTS_OGG_FLAC && isogg); |
306 |
#endif |
285 |
} |
307 |
} |
286 |
#endif |
308 |
#endif |
287 |
|
309 |
|
Lines 295-300
Link Here
|
295 |
dpm.fd = -1; |
317 |
dpm.fd = -1; |
296 |
|
318 |
|
297 |
if (ctx != NULL) { |
319 |
if (ctx != NULL) { |
|
|
320 |
#ifdef LEGACY_FLAC |
298 |
#ifdef AU_OGGFLAC |
321 |
#ifdef AU_OGGFLAC |
299 |
if (flac_options.isogg) { |
322 |
if (flac_options.isogg) { |
300 |
if (ctx->encoder.ogg.stream) { |
323 |
if (ctx->encoder.ogg.stream) { |
Lines 317-322
Link Here
|
317 |
FLAC__stream_encoder_delete(ctx->encoder.flac.stream); |
340 |
FLAC__stream_encoder_delete(ctx->encoder.flac.stream); |
318 |
} |
341 |
} |
319 |
} |
342 |
} |
|
|
343 |
#else |
344 |
if (ctx->encoder.flac.stream) { |
345 |
FLAC__stream_encoder_finish(ctx->encoder.flac.stream); |
346 |
FLAC__stream_encoder_delete(ctx->encoder.flac.stream); |
347 |
} |
348 |
#endif |
320 |
free(ctx); |
349 |
free(ctx); |
321 |
flac_ctx = NULL; |
350 |
flac_ctx = NULL; |
322 |
} |
351 |
} |
Lines 329-334
Link Here
|
329 |
FLAC__StreamMetadata padding; |
358 |
FLAC__StreamMetadata padding; |
330 |
FLAC__StreamMetadata *metadata[4]; |
359 |
FLAC__StreamMetadata *metadata[4]; |
331 |
int num_metadata = 0; |
360 |
int num_metadata = 0; |
|
|
361 |
#ifndef LEGACY_FLAC |
362 |
FLAC__StreamEncoderInitStatus init_status; |
363 |
#endif |
332 |
|
364 |
|
333 |
FLAC_ctx *ctx; |
365 |
FLAC_ctx *ctx; |
334 |
|
366 |
|
Lines 371-376
Link Here
|
371 |
metadata[num_metadata++] = &padding; |
403 |
metadata[num_metadata++] = &padding; |
372 |
} |
404 |
} |
373 |
|
405 |
|
|
|
406 |
#ifdef LEGACY_FLAC |
374 |
#ifdef AU_OGGFLAC |
407 |
#ifdef AU_OGGFLAC |
375 |
if (flac_options.isogg) { |
408 |
if (flac_options.isogg) { |
376 |
if ((ctx->encoder.ogg.stream = OggFLAC__stream_encoder_new()) == NULL) { |
409 |
if ((ctx->encoder.ogg.stream = OggFLAC__stream_encoder_new()) == NULL) { |
Lines 542-547
Link Here
|
542 |
return -1; |
575 |
return -1; |
543 |
} |
576 |
} |
544 |
} |
577 |
} |
|
|
578 |
#else /* !LEGACY_FLAC */ |
579 |
if ((ctx->encoder.flac.stream = FLAC__stream_encoder_new()) == NULL) { |
580 |
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC stream"); |
581 |
flac_session_close(); |
582 |
return -1; |
583 |
} |
584 |
|
585 |
#ifdef AU_OGGFLAC |
586 |
if (flac_options.isogg) { |
587 |
/* set sequential number for serial */ |
588 |
serial_number++; |
589 |
if (serial_number == 1) { |
590 |
srand(time(NULL)); |
591 |
serial_number = rand(); |
592 |
} |
593 |
FLAC__stream_encoder_set_ogg_serial_number(ctx->encoder.flac.stream, serial_number); |
594 |
} |
595 |
#endif /* AU_OGGFLAC */ |
596 |
FLAC__stream_encoder_set_channels(ctx->encoder.flac.stream, nch); |
597 |
/* 16bps only */ |
598 |
FLAC__stream_encoder_set_bits_per_sample(ctx->encoder.flac.stream, 16); |
599 |
|
600 |
FLAC__stream_encoder_set_verify(ctx->encoder.flac.stream, flac_options.verify); |
601 |
|
602 |
if (!FLAC__format_sample_rate_is_valid(dpm.rate)) { |
603 |
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "invalid sampling rate %d", dpm.rate); |
604 |
flac_session_close(); |
605 |
return -1; |
606 |
} |
607 |
FLAC__stream_encoder_set_sample_rate(ctx->encoder.flac.stream, dpm.rate); |
608 |
|
609 |
FLAC__stream_encoder_set_qlp_coeff_precision(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision); |
610 |
/* expensive! */ |
611 |
FLAC__stream_encoder_set_do_qlp_coeff_prec_search(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision_search); |
612 |
|
613 |
if (nch == 2) { |
614 |
FLAC__stream_encoder_set_do_mid_side_stereo(ctx->encoder.flac.stream, flac_options.mid_side); |
615 |
FLAC__stream_encoder_set_loose_mid_side_stereo(ctx->encoder.flac.stream, flac_options.adaptive_mid_side); |
616 |
} |
617 |
|
618 |
FLAC__stream_encoder_set_max_lpc_order(ctx->encoder.flac.stream, flac_options.max_lpc_order); |
619 |
FLAC__stream_encoder_set_min_residual_partition_order(ctx->encoder.flac.stream, flac_options.min_residual_partition_order); |
620 |
FLAC__stream_encoder_set_max_residual_partition_order(ctx->encoder.flac.stream, flac_options.max_residual_partition_order); |
621 |
|
622 |
FLAC__stream_encoder_set_blocksize(ctx->encoder.flac.stream, flac_options.blocksize); |
623 |
|
624 |
if (0 < num_metadata) |
625 |
FLAC__stream_encoder_set_metadata(ctx->encoder.flac.stream, metadata, num_metadata); |
626 |
|
627 |
#ifdef AU_OGGFLAC |
628 |
if (flac_options.isogg) |
629 |
init_status = FLAC__stream_encoder_init_ogg_stream(ctx->encoder.flac.stream, NULL, flac_stream_encoder_write_callback, NULL, NULL, NULL, ctx); |
630 |
else |
631 |
#endif |
632 |
init_status = FLAC__stream_encoder_init_stream(ctx->encoder.flac.stream, flac_stream_encoder_write_callback, NULL, NULL, NULL, ctx); |
633 |
if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { |
634 |
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC encoder (init status: %s)", FLAC__StreamEncoderInitStatusString[init_status]); |
635 |
flac_session_close(); |
636 |
return -1; |
637 |
} |
638 |
#endif |
545 |
|
639 |
|
546 |
return 0; |
640 |
return 0; |
547 |
} |
641 |
} |
Lines 638-644
Link Here
|
638 |
return 0; |
732 |
return 0; |
639 |
} |
733 |
} |
640 |
|
734 |
|
641 |
#ifdef AU_OGGFLAC |
735 |
#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) |
642 |
static FLAC__StreamEncoderWriteStatus |
736 |
static FLAC__StreamEncoderWriteStatus |
643 |
ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, |
737 |
ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, |
644 |
const FLAC__byte buffer[], |
738 |
const FLAC__byte buffer[], |
Lines 658-664
Link Here
|
658 |
static FLAC__StreamEncoderWriteStatus |
752 |
static FLAC__StreamEncoderWriteStatus |
659 |
flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, |
753 |
flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, |
660 |
const FLAC__byte buffer[], |
754 |
const FLAC__byte buffer[], |
|
|
755 |
#ifdef LEGACY_FLAC |
661 |
unsigned bytes, unsigned samples, |
756 |
unsigned bytes, unsigned samples, |
|
|
757 |
#else |
758 |
size_t bytes, unsigned samples, |
759 |
#endif |
662 |
unsigned current_frame, void *client_data) |
760 |
unsigned current_frame, void *client_data) |
663 |
{ |
761 |
{ |
664 |
FLAC_ctx *ctx = (FLAC_ctx *)client_data; |
762 |
FLAC_ctx *ctx = (FLAC_ctx *)client_data; |
Lines 670-675
Link Here
|
670 |
else |
768 |
else |
671 |
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; |
769 |
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; |
672 |
} |
770 |
} |
|
|
771 |
#ifdef LEGACY_FLAC |
673 |
static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, |
772 |
static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, |
674 |
const FLAC__StreamMetadata *metadata, |
773 |
const FLAC__StreamMetadata *metadata, |
675 |
void *client_data) |
774 |
void *client_data) |
Lines 695-700
Link Here
|
695 |
void *client_data) |
794 |
void *client_data) |
696 |
{ |
795 |
{ |
697 |
} |
796 |
} |
|
|
797 |
#endif |
698 |
|
798 |
|
699 |
static int output_data(char *buf, int32 nbytes) |
799 |
static int output_data(char *buf, int32 nbytes) |
700 |
{ |
800 |
{ |
Lines 723-728
Link Here
|
723 |
oggbuf[i] = *s++; |
823 |
oggbuf[i] = *s++; |
724 |
} |
824 |
} |
725 |
|
825 |
|
|
|
826 |
#ifdef LEGACY_FLAC |
726 |
#ifdef AU_OGGFLAC |
827 |
#ifdef AU_OGGFLAC |
727 |
if (flac_options.isogg) { |
828 |
if (flac_options.isogg) { |
728 |
ctx->state.ogg = OggFLAC__stream_encoder_get_state(ctx->encoder.ogg.stream); |
829 |
ctx->state.ogg = OggFLAC__stream_encoder_get_state(ctx->encoder.ogg.stream); |
Lines 793-798
Link Here
|
793 |
return -1; |
894 |
return -1; |
794 |
} |
895 |
} |
795 |
} |
896 |
} |
|
|
897 |
#else /* !LEGACY_FLAC */ |
898 |
ctx->state.flac = FLAC__stream_encoder_get_state(ctx->encoder.flac.stream); |
899 |
if (ctx->state.flac != FLAC__STREAM_ENCODER_OK) { |
900 |
if (ctx->state.flac == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR | |
901 |
FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) { |
902 |
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream verify error (%s)", |
903 |
FLAC__StreamDecoderStateString[FLAC__stream_encoder_get_verify_decoder_state(ctx->encoder.flac.stream)]); |
904 |
} |
905 |
else { |
906 |
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream (%s)", |
907 |
FLAC__StreamEncoderStateString[ctx->state.flac]); |
908 |
} |
909 |
flac_session_close(); |
910 |
return -1; |
911 |
} |
912 |
|
913 |
if (!FLAC__stream_encoder_process_interleaved(ctx->encoder.flac.stream, oggbuf, |
914 |
nbytes / nch / 2 )) { |
915 |
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream"); |
916 |
flac_session_close(); |
917 |
return -1; |
918 |
} |
919 |
#endif |
796 |
ctx->in_bytes += nbytes; |
920 |
ctx->in_bytes += nbytes; |
797 |
|
921 |
|
798 |
free(oggbuf); |
922 |
free(oggbuf); |
Lines 813-818
Link Here
|
813 |
return; |
937 |
return; |
814 |
} |
938 |
} |
815 |
|
939 |
|
|
|
940 |
#ifdef LEGACY_FLAC |
816 |
if (flac_options.isogg) { |
941 |
if (flac_options.isogg) { |
817 |
#ifdef AU_OGGFLAC |
942 |
#ifdef AU_OGGFLAC |
818 |
if ((ctx->state.ogg = OggFLAC__stream_encoder_get_state(ctx->encoder.ogg.stream)) != OggFLAC__STREAM_ENCODER_OK) { |
943 |
if ((ctx->state.ogg = OggFLAC__stream_encoder_get_state(ctx->encoder.ogg.stream)) != OggFLAC__STREAM_ENCODER_OK) { |
Lines 838-843
Link Here
|
838 |
/* fall through */ |
963 |
/* fall through */ |
839 |
} |
964 |
} |
840 |
} |
965 |
} |
|
|
966 |
#else /* !LEGACY_FLAC */ |
967 |
if ((ctx->state.flac = FLAC__stream_encoder_get_state(ctx->encoder.flac.stream)) != FLAC__STREAM_ENCODER_OK) { |
968 |
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream encoder is invalid (%s)", |
969 |
FLAC__StreamEncoderStateString[ctx->state.flac]); |
970 |
/* fall through */ |
971 |
} |
972 |
#endif |
841 |
|
973 |
|
842 |
ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Wrote %lu/%lu bytes(%g%% compressed)", |
974 |
ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Wrote %lu/%lu bytes(%g%% compressed)", |
843 |
ctx->out_bytes, ctx->in_bytes, ((double)ctx->out_bytes / (double)ctx->in_bytes) * 100.); |
975 |
ctx->out_bytes, ctx->in_bytes, ((double)ctx->out_bytes / (double)ctx->in_bytes) * 100.); |