Commit 9c650a56 authored by Josh Coalson's avatar Josh Coalson
Browse files

add undocumented option --apply-replaygain-which-is-not-lossless to flac;...

add undocumented option --apply-replaygain-which-is-not-lossless to flac; required a lot of reorganization; gain_analysis lib renamed to replaygain_analyis; replaygain_synthesis moved out of plugin_common into its own library in share/
parent 628f4efc
......@@ -48,7 +48,10 @@ Package=<4>
Project_Dep_Name grabbag_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name gain_analysis_static
Project_Dep_Name replaygain_analysis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name replaygain_synthesis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name getopt_static
......@@ -132,7 +135,10 @@ Package=<4>
Project_Dep_Name grabbag_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name gain_analysis_static
Project_Dep_Name replaygain_analysis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name replaygain_synthesis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name getopt_static
......@@ -189,7 +195,10 @@ Package=<4>
Project_Dep_Name grabbag_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name gain_analysis_static
Project_Dep_Name replaygain_analysis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name replaygain_synthesis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name getopt_static
......@@ -231,7 +240,19 @@ Package=<4>
###############################################################################
Project: "gain_analysis_static"=.\src\share\gain_analysis\gain_analysis_static.dsp - Package Owner=<4>
Project: "replaygain_analysis_static"=.\src\share\replaygain_analysis\replaygain_analysis_static.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "replaygain_synthesis_static"=.\src\share\replaygain_synthesis\replaygain_synthesis_static.dsp - Package Owner=<4>
Package=<5>
{{{
......@@ -267,7 +288,7 @@ Package=<4>
Project_Dep_Name libFLAC_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name gain_analysis_static
Project_Dep_Name replaygain_analysis_static
End Project Dependency
}}}
......@@ -420,7 +441,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name gain_analysis_static
Project_Dep_Name replaygain_analysis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name getopt_static
......@@ -446,6 +467,9 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name replaygain_synthesis_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name libFLAC_static
End Project Dependency
......
......@@ -19,7 +19,7 @@
# instead of FLAC__ since autoconf triggers off 'AC_' in strings
AC_INIT(src/flac/main.c)
AM_INIT_AUTOMAKE(flac, 1.1.0)
AM_INIT_AUTOMAKE(flac, CVS-20031217)
# Don't automagically regenerate autoconf/automake generated files unless
# explicitly requested. Eases autobuilding -mdz
......@@ -361,9 +361,10 @@ AC_OUTPUT( \
src/plugin_winamp3/Makefile \
src/plugin_xmms/Makefile \
src/share/Makefile \
src/share/gain_analysis/Makefile \
src/share/getopt/Makefile \
src/share/grabbag/Makefile \
src/share/replaygain_analysis/Makefile \
src/share/replaygain_synthesis/Makefile \
src/share/utf8/Makefile \
src/test_grabbag/Makefile \
src/test_grabbag/cuesheet/Makefile \
......
......@@ -5,7 +5,8 @@ AUTOMAKE_OPTIONS = foreign
SUBDIRS = grabbag
EXTRA_DIST = \
gain_analysis.h \
getopt.h \
grabbag.h \
replaygain_analysis.h \
replaygain_synthesis.h \
utf8.h
......@@ -17,7 +17,7 @@
*/
/*
* This wraps the gain_analysis lib, which is LGPL. This wrapper
* This wraps the replaygain_analysis lib, which is LGPL. This wrapper
* allows analysis of different input resolutions by automatically
* scaling the input signal
*/
......
......@@ -16,16 +16,18 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FLAC__PLUGIN_COMMON__REPLAYGAIN_SYNTHESIS_H
#define FLAC__PLUGIN_COMMON__REPLAYGAIN_SYNTHESIS_H
#ifndef FLAC__SHARE__REPLAYGAIN_SYNTHESIS_H
#define FLAC__SHARE__REPLAYGAIN_SYNTHESIS_H
#include "defs.h"
#include <stdlib.h> /* for size_t */
#include "FLAC/ordinals.h"
#define FLAC_SHARE__MAX_SUPPORTED_CHANNELS 2
typedef enum {
NOISE_SHAPING_NONE = 0,
NOISE_SHAPING_LOW = 1,
NOISE_SHAPING_MEDUIM = 2,
NOISE_SHAPING_MEDIUM = 2,
NOISE_SHAPING_HIGH = 3
} NoiseShaping;
......@@ -34,16 +36,16 @@ typedef struct {
FLAC__uint64 Mask;
double Add;
float Dither;
float ErrorHistory [FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS] [16]; /* 16th order Noise shaping */
float DitherHistory [FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS] [16];
int LastRandomNumber [FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
float ErrorHistory [FLAC_SHARE__MAX_SUPPORTED_CHANNELS] [16]; /* 16th order Noise shaping */
float DitherHistory [FLAC_SHARE__MAX_SUPPORTED_CHANNELS] [16];
int LastRandomNumber [FLAC_SHARE__MAX_SUPPORTED_CHANNELS];
unsigned LastHistoryIndex;
NoiseShaping ShapingType;
} DitherContext;
void FLAC__plugin_common__init_dither_context(DitherContext *dither, int bits, int shapingtype);
void FLAC__replaygain_synthesis__init_dither_context(DitherContext *dither, int bits, int shapingtype);
/* scale = (float) pow(10., (double)replaygain * 0.05); */
int FLAC__plugin_common__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const float scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context);
size_t FLAC__replaygain_synthesis__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, FLAC__bool unsigned_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const float scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context);
#endif
......@@ -44,8 +44,9 @@ flac_SOURCES = \
flac_LDADD = \
$(NEED_OGGFLAC_LIB) \
$(top_builddir)/src/share/grabbag/libgrabbag.la \
$(top_builddir)/src/share/gain_analysis/libgain_analysis.la \
$(top_builddir)/src/share/getopt/libgetopt.a \
$(top_builddir)/src/share/replaygain_analysis/libreplaygain_analysis.la \
$(top_builddir)/src/share/replaygain_synthesis/libreplaygain_synthesis.la \
$(top_builddir)/src/share/utf8/libutf8.la \
$(top_builddir)/src/libFLAC/libFLAC.la \
@OGG_LIBS@ \
......
......@@ -24,16 +24,16 @@ topdir = ../..
PROGRAM_NAME = flac
ifeq ($(DARWIN_BUILD),yes)
INCLUDES = -I./include -I$(topdir)/include
LIBS = -lgrabbag -lFLAC -lgain_analysis -lgetopt -lutf8 -lc -lm
LIBS = -lgrabbag -lFLAC -lreplaygain_analysis -lreplaygain_synthesis -lgetopt -lutf8 -lc -lm
else
#@@@ TODO: conditionalize ogg includes, defines, and -logg
ifeq ($(SOLARIS_BUILD),yes)
INCLUDES = -I./include -I$(topdir)/include -I$(HOME)/local/include -DFLAC__HAS_OGG
LIBS = -lgrabbag -lOggFLAC -lFLAC -lgain_analysis -lgetopt -lutf8 -lm -L$(HOME)/local/lib -logg
LIBS = -lgrabbag -lOggFLAC -lFLAC -lreplaygain_analysis -lreplaygain_synthesis -lgetopt -lutf8 -lm -L$(HOME)/local/lib -logg
else
#@@@ TODO: conditionalize ogg includes, defines, and -logg
INCLUDES = -I./include -I$(topdir)/include -I$(HOME)/local/include -DFLAC__HAS_OGG
LIBS = -lgrabbag -lOggFLAC -lFLAC -lgain_analysis -lgetopt -lutf8 -lm -L$(HOME)/local/lib -logg
LIBS = -lgrabbag -lOggFLAC -lFLAC -lreplaygain_analysis -lreplaygain_synthesis -lgetopt -lutf8 -lm -L$(HOME)/local/lib -logg
endif
endif
......
......@@ -31,6 +31,7 @@
#include <string.h> /* for strcmp() */
#include "FLAC/all.h"
#include "share/grabbag.h"
#include "share/replaygain_synthesis.h"
#include "decode.h"
#ifdef FLAC__HAS_OGG
......@@ -46,6 +47,13 @@ typedef struct {
FLAC__bool is_aiff_out;
FLAC__bool is_wave_out;
FLAC__bool continue_through_decode_errors;
struct {
replaygain_synthesis_spec_t spec;
double scale;
DitherContext dither_context;
} replaygain;
FLAC__bool test_only;
FLAC__bool analysis_mode;
analysis_options aopts;
......@@ -97,7 +105,7 @@ static FLAC__bool is_big_endian_host_;
/*
* local routines
*/
static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename);
static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename);
static void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred);
static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, decode_options_t decode_options, const char *infilename);
static FLAC__bool DecoderSession_process(DecoderSession *d);
......@@ -144,6 +152,7 @@ int flac__decode_aiff(const char *infilename, const char *outfilename, FLAC__boo
/*is_aiff_out=*/true,
/*is_wave_out=*/false,
options.common.continue_through_decode_errors,
options.common.replaygain_synthesis_spec,
analysis_mode,
aopts,
&options.common.skip_specification,
......@@ -179,6 +188,7 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool
/*is_aiff_out=*/false,
/*is_wave_out=*/true,
options.common.continue_through_decode_errors,
options.common.replaygain_synthesis_spec,
analysis_mode,
aopts,
&options.common.skip_specification,
......@@ -217,6 +227,7 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
/*is_aiff_out=*/false,
/*is_wave_out=*/false,
options.common.continue_through_decode_errors,
options.common.replaygain_synthesis_spec,
analysis_mode,
aopts,
&options.common.skip_specification,
......@@ -236,7 +247,7 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
return DecoderSession_finish_ok(&decoder_session);
}
FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename)
FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename)
{
#ifdef FLAC__HAS_OGG
d->is_ogg = is_ogg;
......@@ -248,6 +259,9 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
d->is_aiff_out = is_aiff_out;
d->is_wave_out = is_wave_out;
d->continue_through_decode_errors = continue_through_decode_errors;
d->replaygain.spec = replaygain_synthesis_spec;
d->replaygain.scale = 0.0;
/* d->replaygain.dither_context gets initialized later once we know the sample resolution */
d->test_only = (0 == outfilename);
d->analysis_mode = analysis_mode;
d->aopts = aopts;
......@@ -338,6 +352,8 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_o
if(!decode_options.use_first_serial_number)
OggFLAC__stream_decoder_set_serial_number(decoder_session->decoder.ogg.stream, decode_options.serial_number);
if (decoder_session->replaygain.spec.apply)
OggFLAC__stream_decoder_set_metadata_respond(decoder_session->decoder.ogg.stream, FLAC__METADATA_TYPE_VORBIS_COMMENT);
OggFLAC__stream_decoder_set_read_callback(decoder_session->decoder.ogg.stream, read_callback);
/*
......@@ -369,6 +385,8 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_o
FLAC__file_decoder_set_md5_checking(decoder_session->decoder.flac.file, true);
FLAC__file_decoder_set_filename(decoder_session->decoder.flac.file, infilename);
if (decoder_session->replaygain.spec.apply)
FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_VORBIS_COMMENT);
/*
* The three ugly casts here are to 'downcast' the 'void *' argument of
* the callback down to 'FLAC__FileDecoder *'.
......@@ -800,7 +818,25 @@ FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__F
flac__analyze_frame(frame, decoder_session->frame_counter-1, decoder_session->aopts, fout);
}
else if(!decoder_session->test_only) {
if(bps == 8) {
if (decoder_session->replaygain.spec.apply) {
const size_t n = FLAC__replaygain_synthesis__apply_gain(
u8buffer,
is_big_endian,
is_unsigned_samples,
buffer,
wide_samples,
channels,
bps, /* source_bps */
bps, /* target_bps */
decoder_session->replaygain.scale,
decoder_session->replaygain.spec.limiter == RGSS_LIMIT__HARD, /* hard_limit */
decoder_session->replaygain.spec.noise_shaping != NOISE_SHAPING_NONE, /* do_dithering */
&decoder_session->replaygain.dither_context
);
if(flac__utils_fwrite(u8buffer, 1, n, fout) != n)
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
else if(bps == 8) {
if(is_unsigned_samples) {
for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
for(channel = 0; channel < channels; channel++, sample++)
......@@ -1047,6 +1083,23 @@ void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata
}
}
}
else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
if (decoder_session->replaygain.spec.apply) {
double gain, peak;
if (!(decoder_session->replaygain.spec.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, &gain, &peak))) {
fprintf(stderr, "%s: WARNING: can't get %s ReplayGain tag\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track");
}
else {
const char *ls[] = { "no", "peak", "hard" };
const char *ns[] = { "no", "low", "medium", "high" };
decoder_session->replaygain.scale = grabbag__replaygain_compute_scale_factor(peak, gain, decoder_session->replaygain.spec.preamp, decoder_session->replaygain.spec.limiter == RGSS_LIMIT__PEAK);
assert(decoder_session->bps > 0 && decoder_session->bps <= 32);
FLAC__replaygain_synthesis__init_dither_context(&decoder_session->replaygain.dither_context, decoder_session->bps, decoder_session->replaygain.spec.noise_shaping);
fprintf(stderr, "%s: INFO: applying %s ReplayGain (gain=%0.2fdB+preamp=%0.1fdB, %s noise shaping, %s limiting) to output\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", gain, decoder_session->replaygain.spec.preamp, ns[decoder_session->replaygain.spec.noise_shaping], ls[decoder_session->replaygain.spec.limiter]);
fprintf(stderr, "%s: WARNING: applying ReplayGain is not lossless\n", decoder_session->inbasefilename);
}
}
}
}
void error_callback(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
......
......@@ -21,14 +21,24 @@
#include "analyze.h"
#include "utils.h"
#include "share/replaygain_synthesis.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
typedef struct {
FLAC__bool apply;
FLAC__bool use_album_gain; /* false => use track gain */
enum { RGSS_LIMIT__NONE, RGSS_LIMIT__PEAK, RGSS_LIMIT__HARD} limiter;
NoiseShaping noise_shaping;
double preamp;
} replaygain_synthesis_spec_t;
typedef struct {
FLAC__bool verbose;
FLAC__bool continue_through_decode_errors;
replaygain_synthesis_spec_t replaygain_synthesis_spec;
#ifdef FLAC__HAS_OGG
FLAC__bool is_ogg;
FLAC__bool use_first_serial_number;
......
......@@ -1825,6 +1825,8 @@ void ogg_stream_encoder_metadata_callback(const OggFLAC__StreamEncoder *encoder,
void ogg_file_encoder_progress_callback(const OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
{
(void)encoder;
flac_file_encoder_progress_callback(0, bytes_written, samples_written, frames_written, total_frames_estimate, client_data);
}
......
......@@ -51,7 +51,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 ..\..\obj\release\lib\grabbag_static.lib ..\..\obj\release\lib\libOggFLAC_static.lib ..\..\obj\release\lib\libFLAC_static.lib ..\..\obj\release\lib\gain_analysis_static.lib ..\..\obj\release\lib\getopt_static.lib ..\..\obj\release\lib\utf8_static.lib ..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 ..\..\obj\release\lib\grabbag_static.lib ..\..\obj\release\lib\libOggFLAC_static.lib ..\..\obj\release\lib\libFLAC_static.lib ..\..\obj\release\lib\replaygain_analysis_static.lib ..\..\obj\release\lib\replaygain_synthesis_static.lib ..\..\obj\release\lib\getopt_static.lib ..\..\obj\release\lib\utf8_static.lib ..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "flac - Win32 Debug"
......@@ -76,7 +76,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ..\..\obj\debug\lib\grabbag_static.lib ..\..\obj\debug\lib\libOggFLAC_static.lib ..\..\obj\debug\lib\libFLAC_static.lib ..\..\obj\debug\lib\gain_analysis_static.lib ..\..\obj\debug\lib\getopt_static.lib ..\..\obj\debug\lib\utf8_static.lib ..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ..\..\obj\debug\lib\grabbag_static.lib ..\..\obj\debug\lib\libOggFLAC_static.lib ..\..\obj\debug\lib\libFLAC_static.lib ..\..\obj\debug\lib\replaygain_analysis_static.lib ..\..\obj\debug\lib\replaygain_synthesis_static.lib ..\..\obj\debug\lib\getopt_static.lib ..\..\obj\debug\lib\utf8_static.lib ..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
......
......@@ -85,103 +85,104 @@ static struct share__option long_options_[] = {
/*
* general options
*/
{ "help", 0, 0, 'h' },
{ "explain", 0, 0, 'H' },
{ "version", 0, 0, 'v' },
{ "decode", 0, 0, 'd' },
{ "analyze", 0, 0, 'a' },
{ "test", 0, 0, 't' },
{ "stdout", 0, 0, 'c' },
{ "silent", 0, 0, 's' },
{ "delete-input-file", 0, 0, 0 },
{ "output-prefix", 1, 0, 0 },
{ "output-name", 1, 0, 'o' },
{ "skip", 1, 0, 0 },
{ "until", 1, 0, 0 },
{ "help" , share__no_argument, 0, 'h' },
{ "explain" , share__no_argument, 0, 'H' },
{ "version" , share__no_argument, 0, 'v' },
{ "decode" , share__no_argument, 0, 'd' },
{ "analyze" , share__no_argument, 0, 'a' },
{ "test" , share__no_argument, 0, 't' },
{ "stdout" , share__no_argument, 0, 'c' },
{ "silent" , share__no_argument, 0, 's' },
{ "delete-input-file", share__no_argument, 0, 0 },
{ "output-prefix" , share__required_argument, 0, 0 },
{ "output-name" , share__required_argument, 0, 'o' },
{ "skip" , share__required_argument, 0, 0 },
{ "until" , share__required_argument, 0, 0 },
/*
* decoding options
*/
{ "decode-through-errors", 0, 0, 'F' },
{ "decode-through-errors", share__no_argument, 0, 'F' },
{ "apply-replaygain-which-is-not-lossless", share__optional_argument, 0, 0 }, /* undocumented */
/*
* encoding options
*/
{ "cuesheet", 1, 0, 0 },
{ "no-cued-seekpoints", 0, 0, 0 },
{ "tag", 1, 0, 'T' },
{ "compression-level-0", 0, 0, '0' },
{ "compression-level-1", 0, 0, '1' },
{ "compression-level-2", 0, 0, '2' },
{ "compression-level-3", 0, 0, '3' },
{ "compression-level-4", 0, 0, '4' },
{ "compression-level-5", 0, 0, '5' },
{ "compression-level-6", 0, 0, '6' },
{ "compression-level-7", 0, 0, '7' },
{ "compression-level-8", 0, 0, '8' },
{ "compression-level-9", 0, 0, '9' },
{ "best", 0, 0, '8' },
{ "fast", 0, 0, '0' },
{ "super-secret-totally-impractical-compression-level", 0, 0, 0 },
{ "verify", 0, 0, 'V' },
{ "force-aiff-format", 0, 0, 0 },
{ "force-raw-format", 0, 0, 0 },
{ "lax", 0, 0, 0 },
{ "replay-gain", 0, 0, 0 },
{ "sector-align", 0, 0, 0 },
{ "seekpoint", 1, 0, 'S' },
{ "padding", 1, 0, 'P' },
{ "cuesheet" , share__required_argument, 0, 0 },
{ "no-cued-seekpoints" , share__no_argument, 0, 0 },
{ "tag" , share__required_argument, 0, 'T' },
{ "compression-level-0" , share__no_argument, 0, '0' },
{ "compression-level-1" , share__no_argument, 0, '1' },
{ "compression-level-2" , share__no_argument, 0, '2' },
{ "compression-level-3" , share__no_argument, 0, '3' },
{ "compression-level-4" , share__no_argument, 0, '4' },
{ "compression-level-5" , share__no_argument, 0, '5' },
{ "compression-level-6" , share__no_argument, 0, '6' },
{ "compression-level-7" , share__no_argument, 0, '7' },
{ "compression-level-8" , share__no_argument, 0, '8' },
{ "compression-level-9" , share__no_argument, 0, '9' },
{ "best" , share__no_argument, 0, '8' },
{ "fast" , share__no_argument, 0, '0' },
{ "super-secret-totally-impractical-compression-level", share__no_argument, 0, 0 },
{ "verify" , share__no_argument, 0, 'V' },
{ "force-aiff-format" , share__no_argument, 0, 0 },
{ "force-raw-format" , share__no_argument, 0, 0 },
{ "lax" , share__no_argument, 0, 0 },
{ "replay-gain" , share__no_argument, 0, 0 },
{ "sector-align" , share__no_argument, 0, 0 },
{ "seekpoint" , share__required_argument, 0, 'S' },
{ "padding" , share__required_argument, 0, 'P' },
#ifdef FLAC__HAS_OGG
{ "ogg", 0, 0, 0 },
{ "serial-number", 1, 0, 0 },
{ "ogg" , share__no_argument, 0, 0 },
{ "serial-number" , share__required_argument, 0, 0 },
#endif
{ "blocksize", 1, 0, 'b' },
{ "exhaustive-model-search", 0, 0, 'e' },
{ "max-lpc-order", 1, 0, 'l' },
{ "mid-side", 0, 0, 'm' },
{ "adaptive-mid-side", 0, 0, 'M' },
{ "qlp-coeff-precision-search", 0, 0, 'p' },
{ "qlp-coeff-precision", 1, 0, 'q' },
{ "rice-partition-order", 1, 0, 'r' },
{ "endian", 1, 0, 0 },
{ "channels", 1, 0, 0 },
{ "bps", 1, 0, 0 },
{ "sample-rate", 1, 0, 0 },
{ "sign", 1, 0, 0 },
{ "blocksize" , share__required_argument, 0, 'b' },
{ "exhaustive-model-search" , share__no_argument, 0, 'e' },
{ "max-lpc-order" , share__required_argument, 0, 'l' },
{ "mid-side" , share__no_argument, 0, 'm' },
{ "adaptive-mid-side" , share__no_argument, 0, 'M' },
{ "qlp-coeff-precision-search", share__no_argument, 0, 'p' },
{ "qlp-coeff-precision" , share__required_argument, 0, 'q' },
{ "rice-partition-order" , share__required_argument, 0, 'r' },
{ "endian" , share__required_argument, 0, 0 },
{ "channels" , share__required_argument, 0, 0 },
{ "bps" , share__required_argument, 0, 0 },
{ "sample-rate" , share__required_argument, 0, 0 },
{ "sign" , share__required_argument, 0, 0 },
/*
* analysis options
*/
{ "residual-gnu-plot", 0, 0, 0 },
{ "residual-text", 0, 0, 0 },
{ "residual-gnu-plot", share__no_argument, 0, 0 },
{ "residual-text", share__no_argument, 0, 0 },
/*
* negatives
*/
{ "no-decode-through-errors", 0, 0, 0 },
{ "no-silent", 0, 0, 0 },
{ "no-seektable", 0, 0, 0 },
{ "no-delete-input-file", 0, 0, 0 },
{ "no-replay-gain", 0, 0, 0 },
{ "no-sector-align", 0, 0, 0 },
{ "no-lax", 0, 0, 0 },
{ "no-decode-through-errors" , share__no_argument, 0, 0 },
{ "no-silent" , share__no_argument, 0, 0 },
{ "no-seektable" , share__no_argument, 0, 0 },
{ "no-delete-input-file" , share__no_argument, 0, 0 },
{ "no-replay-gain" , share__no_argument, 0, 0 },
{ "no-sector-align" , share__no_argument, 0, 0 },
{ "no-lax" , share__no_argument, 0, 0 },
#ifdef FLAC__HAS_OGG
{ "no-ogg", 0, 0, 0 },
{ "no-ogg" , share__no_argument, 0, 0 },
#endif
{ "no-exhaustive-model-search", 0, 0, 0 },
{ "no-mid-side", 0, 0, 0 },
{ "no-adaptive-mid-side", 0, 0, 0 },
{ "no-qlp-coeff-prec-search", 0, 0, 0 },
{ "no-padding", 0, 0, 0 },
{ "no-verify", 0, 0, 0 },
{ "no-residual-gnuplot", 0, 0, 0 },
{ "no-residual-text", 0, 0, 0 },
{ "no-exhaustive-model-search", share__no_argument, 0, 0 },
{ "no-mid-side" , share__no_argument, 0, 0 },
{ "no-adaptive-mid-side" , share__no_argument, 0, 0 },
{ "no-qlp-coeff-prec-search" , share__no_argument, 0, 0 },
{ "no-padding" , share__no_argument, 0, 0 },
{ "no-verify" , share__no_argument, 0, 0 },
{ "no-residual-gnuplot" , share__no_argument, 0, 0 },
{ "no-residual-text" , share__no_argument, 0, 0 },
/*
* undocumented debugging options for the test suite
*/
{ "disable-constant-subframes", 0, 0, 0 },
{ "disable-fixed-subframes", 0, 0, 0 },
{ "disable-verbatim-subframes", 0, 0, 0 },
{ "disable-constant-subframes", share__no_argument, 0, 0 },
{ "disable-fixed-subframes" , share__no_argument, 0, 0 },
{ "disable-verbatim-subframes", share__no_argument, 0, 0 },
{0, 0, 0, 0}
};
......@@ -199,6 +200,7 @@ static struct {
FLAC__bool verify;
FLAC__bool verbose;
FLAC__bool continue_through_decode_errors;
replaygain_synthesis_spec_t replaygain_synthesis_spec;
FLAC__bool lax;
FLAC__bool test_only;
FLAC__bool analyze;
......@@ -520,6 +522,11 @@ FLAC__bool init_options()
option_values.verify = false;
option_values.verbose = true;
option_values.continue_through_decode_errors = false;
option_values.replaygain_synthesis_spec.apply = false;
option_values.replaygain_synthesis_spec.use_album_gain = true;
option_values.replaygain_synthesis_spec.limiter = RGSS_LIMIT__HARD;
option_values.replaygain_synthesis_spec.noise_shaping = NOISE_SHAPING_LOW;
option_values.replaygain_synthesis_spec.preamp = 0.0;
option_values.lax = false;
option_values.test_only = false;
option_values.analyze = false;
......@@ -635,6 +642,31 @@ int parse_option(int short_option, const char *long_option, const char *option_a
FLAC__ASSERT(0 != option_argument);
option_values.until_specification = option_argument;
}
else if(0 == strcmp(long_option, "apply-replaygain-which-is-not-lossless")) {
option_values.replaygain_synthesis_spec.apply = true;