diff -ru TiMidity++-2.13.2/timidity/flac_a.c TiMidity++-2.13.2-b2/timidity/flac_a.c --- TiMidity++-2.13.2/timidity/flac_a.c 2004-05-22 21:35:44.000000000 -0700 +++ TiMidity++-2.13.2-b2/timidity/flac_a.c 2006-10-31 15:39:59.000000000 -0800 @@ -38,14 +38,21 @@ #if defined(AU_FLAC_DLL) || defined(AU_OGGFLAC_DLL) #include -#define FLAC__EXPORT_H /* don't include "OggFLAC/export.h" */ -#define FLAC_API -#define OggFLAC__EXPORT_H /* don't include "FLAC/export.h" */ -#define OggFLAC_API +#include /* need export.h to figure out API version from FLAC_API_VERSION_CURRENT */ +#undef FLAC_API +#undef OggFLAC_API +#endif + +/* by LEGACY_FLAC we mean before FLAC 1.1.3 */ +/* in FLAC 1.1.3, libOggFLAC is merged into libFLAC and all encoding layers are merged into the stream encoder */ +#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT < 8 +#define LEGACY_FLAC +#else +#undef LEGACY_FLAC #endif #include -#ifdef AU_OGGFLAC +#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) #include #endif @@ -100,17 +107,21 @@ unsigned long out_bytes; union { FLAC__StreamEncoderState flac; +#ifdef LEGACY_FLAC FLAC__SeekableStreamEncoderState s_flac; #ifdef AU_OGGFLAC OggFLAC__StreamEncoderState ogg; #endif +#endif } state; union { union { FLAC__StreamEncoder *stream; +#ifdef LEGACY_FLAC FLAC__SeekableStreamEncoder *s_stream; +#endif } flac; -#ifdef AU_OGGFLAC +#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) union { OggFLAC__StreamEncoder *stream; } ogg; @@ -119,7 +130,7 @@ } FLAC_ctx; typedef struct { -#ifdef AU_OGGFLAC +#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) int isogg; #endif int verify; @@ -138,7 +149,7 @@ /* default compress level is 5 */ FLAC_options flac_options = { -#ifdef AU_OGGFLAC +#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) 0, /* isogg */ #endif 0, /* verify */ @@ -158,7 +169,7 @@ static long serial_number = 0; FLAC_ctx *flac_ctx = NULL; -#ifdef AU_OGGFLAC +#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) static FLAC__StreamEncoderWriteStatus ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], @@ -168,8 +179,13 @@ static FLAC__StreamEncoderWriteStatus flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], +#ifdef LEGACY_FLAC unsigned bytes, unsigned samples, +#else + size_t bytes, unsigned samples, +#endif unsigned current_frame, void *client_data); +#ifdef LEGACY_FLAC static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); @@ -181,6 +197,7 @@ static void flac_seekable_stream_encoder_metadata_callback(const FLAC__SeekableStreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); +#endif /* preset */ void flac_set_compression_level(int compression_level) @@ -295,6 +312,7 @@ dpm.fd = -1; if (ctx != NULL) { +#ifdef LEGACY_FLAC #ifdef AU_OGGFLAC if (flac_options.isogg) { if (ctx->encoder.ogg.stream) { @@ -317,6 +335,12 @@ FLAC__stream_encoder_delete(ctx->encoder.flac.stream); } } +#else + if (ctx->encoder.flac.stream) { + FLAC__stream_encoder_finish(ctx->encoder.flac.stream); + FLAC__stream_encoder_delete(ctx->encoder.flac.stream); + } +#endif free(ctx); flac_ctx = NULL; } @@ -329,6 +353,9 @@ FLAC__StreamMetadata padding; FLAC__StreamMetadata *metadata[4]; int num_metadata = 0; +#ifndef LEGACY_FLAC + FLAC__StreamEncoderInitStatus init_status; +#endif FLAC_ctx *ctx; @@ -371,6 +398,7 @@ metadata[num_metadata++] = &padding; } +#ifdef LEGACY_FLAC #ifdef AU_OGGFLAC if (flac_options.isogg) { if ((ctx->encoder.ogg.stream = OggFLAC__stream_encoder_new()) == NULL) { @@ -542,6 +570,67 @@ return -1; } } +#else /* !LEGACY_FLAC */ + if ((ctx->encoder.flac.stream = FLAC__stream_encoder_new()) == NULL) { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC stream"); + flac_session_close(); + return -1; + } + +#ifdef AU_OGGFLAC + if (flac_options.isogg) { + /* set sequential number for serial */ + serial_number++; + if (serial_number == 1) { + srand(time(NULL)); + serial_number = rand(); + } + FLAC__stream_encoder_set_ogg_serial_number(ctx->encoder.flac.stream, serial_number); + } +#endif /* AU_OGGFLAC */ + FLAC__stream_encoder_set_channels(ctx->encoder.flac.stream, nch); + /* 16bps only */ + FLAC__stream_encoder_set_bits_per_sample(ctx->encoder.flac.stream, 16); + + FLAC__stream_encoder_set_verify(ctx->encoder.flac.stream, flac_options.verify); + + if (!FLAC__format_sample_rate_is_valid(dpm.rate)) { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "invalid sampling rate %d", dpm.rate); + flac_session_close(); + return -1; + } + FLAC__stream_encoder_set_sample_rate(ctx->encoder.flac.stream, dpm.rate); + + FLAC__stream_encoder_set_qlp_coeff_precision(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision); + /* expensive! */ + FLAC__stream_encoder_set_do_qlp_coeff_prec_search(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision_search); + + if (nch == 2) { + FLAC__stream_encoder_set_do_mid_side_stereo(ctx->encoder.flac.stream, flac_options.mid_side); + FLAC__stream_encoder_set_loose_mid_side_stereo(ctx->encoder.flac.stream, flac_options.adaptive_mid_side); + } + + FLAC__stream_encoder_set_max_lpc_order(ctx->encoder.flac.stream, flac_options.max_lpc_order); + FLAC__stream_encoder_set_min_residual_partition_order(ctx->encoder.flac.stream, flac_options.min_residual_partition_order); + FLAC__stream_encoder_set_max_residual_partition_order(ctx->encoder.flac.stream, flac_options.max_residual_partition_order); + + FLAC__stream_encoder_set_blocksize(ctx->encoder.flac.stream, flac_options.blocksize); + + if (0 < num_metadata) + FLAC__stream_encoder_set_metadata(ctx->encoder.flac.stream, metadata, num_metadata); + +#ifdef AU_OGGFLAC + if (flac_options.isogg) + init_status = FLAC__stream_encoder_init_ogg_stream(ctx->encoder.flac.stream, flac_stream_encoder_write_callback, NULL, NULL, NULL, ctx); + else +#endif + init_status = FLAC__stream_encoder_init_stream(ctx->encoder.flac.stream, flac_stream_encoder_write_callback, NULL, NULL, NULL, ctx); + if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC encoder (init status: %s)", FLAC__StreamEncoderInitStatusString[init_status]); + flac_session_close(); + return -1; + } +#endif return 0; } @@ -638,7 +727,7 @@ return 0; } -#ifdef AU_OGGFLAC +#if defined(LEGACY_FLAC) && defined(AU_OGGFLAC) static FLAC__StreamEncoderWriteStatus ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], @@ -658,7 +747,11 @@ static FLAC__StreamEncoderWriteStatus flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], +#ifdef LEGACY_FLAC unsigned bytes, unsigned samples, +#else + size_t bytes, unsigned samples, +#endif unsigned current_frame, void *client_data) { FLAC_ctx *ctx = (FLAC_ctx *)client_data; @@ -670,6 +763,7 @@ else return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; } +#ifdef LEGACY_FLAC static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data) @@ -695,6 +789,7 @@ void *client_data) { } +#endif static int output_data(char *buf, int32 nbytes) { @@ -723,6 +818,7 @@ oggbuf[i] = *s++; } +#ifdef LEGACY_FLAC #ifdef AU_OGGFLAC if (flac_options.isogg) { ctx->state.ogg = OggFLAC__stream_encoder_get_state(ctx->encoder.ogg.stream); @@ -793,6 +889,29 @@ return -1; } } +#else /* !LEGACY_FLAC */ + ctx->state.flac = FLAC__stream_encoder_get_state(ctx->encoder.flac.stream); + if (ctx->state.flac != FLAC__STREAM_ENCODER_OK) { + if (ctx->state.flac == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR | + FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream verify error (%s)", + FLAC__StreamDecoderStateString[FLAC__stream_encoder_get_verify_decoder_state(ctx->encoder.flac.stream)]); + } + else { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream (%s)", + FLAC__StreamEncoderStateString[ctx->state.flac]); + } + flac_session_close(); + return -1; + } + + if (!FLAC__stream_encoder_process_interleaved(ctx->encoder.flac.stream, oggbuf, + nbytes / nch / 2 )) { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream"); + flac_session_close(); + return -1; + } +#endif ctx->in_bytes += nbytes; free(oggbuf); @@ -813,6 +932,7 @@ return; } +#ifdef LEGACY_FLAC if (flac_options.isogg) { #ifdef AU_OGGFLAC if ((ctx->state.ogg = OggFLAC__stream_encoder_get_state(ctx->encoder.ogg.stream)) != OggFLAC__STREAM_ENCODER_OK) { @@ -838,6 +958,13 @@ /* fall through */ } } +#else /* !LEGACY_FLAC */ + if ((ctx->state.flac = FLAC__stream_encoder_get_state(ctx->encoder.flac.stream)) != FLAC__STREAM_ENCODER_OK) { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream encoder is invalid (%s)", + FLAC__StreamEncoderStateString[ctx->state.flac]); + /* fall through */ + } +#endif ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Wrote %lu/%lu bytes(%g%% compressed)", ctx->out_bytes, ctx->in_bytes, ((double)ctx->out_bytes / (double)ctx->in_bytes) * 100.);