Josh Coalson
2009-01-07 07:03:17 +00:00
parent f36d4567c1
commit c9ed238c3d
8 changed files with 104 additions and 40 deletions

View File

@@ -63,6 +63,7 @@
<ul> <ul>
<li>The <span class="argument"><a href="documentation_tools_flac.html#flac_options_sector_align">--sector-align</a></span> option of <span class="commandname">flac</span> has been deprecated and may not exist in future versions. <a href="http://www.etree.org/shnutils/shntool/">shntool</a> provides similar functionality.</li> <li>The <span class="argument"><a href="documentation_tools_flac.html#flac_options_sector_align">--sector-align</a></span> option of <span class="commandname">flac</span> has been deprecated and may not exist in future versions. <a href="http://www.etree.org/shnutils/shntool/">shntool</a> provides similar functionality.</li>
<li>Support for the RF64 and Wave64 formats in <span class="commandname">flac</span> (see below).</li> <li>Support for the RF64 and Wave64 formats in <span class="commandname">flac</span> (see below).</li>
<li>Better handling of cuesheets with non-CD-DA sample rates.</li>
</ul> </ul>
</li> </li>
<li> <li>
@@ -83,6 +84,7 @@
<li>Added support for encoding from and decoding to the RF64 format, and a new corresponding option <span class="argument"><a href="#flac_options_force_rf64_format" />--force-rf64-format</a></span>. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1762502&amp;group_id=13478&amp;atid=363478">SF #1762502</a>). <span class="argument"><a href="documentation_tools_flac.html#flac_options_keep_foreign_metadata">--keep-foreign-metadata</a></span> is also supported.</li> <li>Added support for encoding from and decoding to the RF64 format, and a new corresponding option <span class="argument"><a href="#flac_options_force_rf64_format" />--force-rf64-format</a></span>. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1762502&amp;group_id=13478&amp;atid=363478">SF #1762502</a>). <span class="argument"><a href="documentation_tools_flac.html#flac_options_keep_foreign_metadata">--keep-foreign-metadata</a></span> is also supported.</li>
<li>Added support for encoding from and decoding to the Sony Wave64 format, and a new corresponding option <span class="argument"><a href="#flac_options_force_wave64_format" />--force-wave64-format</a></span>. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1769582&amp;group_id=13478&amp;atid=363478">SF #1769582</a>). <span class="argument"><a href="documentation_tools_flac.html#flac_options_keep_foreign_metadata">--keep-foreign-metadata</a></span> is also supported.</li> <li>Added support for encoding from and decoding to the Sony Wave64 format, and a new corresponding option <span class="argument"><a href="#flac_options_force_wave64_format" />--force-wave64-format</a></span>. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1769582&amp;group_id=13478&amp;atid=363478">SF #1769582</a>). <span class="argument"><a href="documentation_tools_flac.html#flac_options_keep_foreign_metadata">--keep-foreign-metadata</a></span> is also supported.</li>
<li>Added new options <span class="argument"><a href="documentation_tools_flac.html#flac_options_preserve_modtime">--preserve-modtime</a></span> and <span class="argument"><a href="documentation_tools_flac.html#flac_options_no_preserve_modtime">--no-preserve-modtime</a></span> to specify whether or not output files should copy the timestamp and permissions from their input files. The default is <span class="argument"><a href="documentation_tools_flac.html#flac_options_preserve_modtime">--preserve-modtime</a></span> as in previous versions. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1805428&amp;group_id=13478&amp;atid=363478">SF #1805428</a>).</li> <li>Added new options <span class="argument"><a href="documentation_tools_flac.html#flac_options_preserve_modtime">--preserve-modtime</a></span> and <span class="argument"><a href="documentation_tools_flac.html#flac_options_no_preserve_modtime">--no-preserve-modtime</a></span> to specify whether or not output files should copy the timestamp and permissions from their input files. The default is <span class="argument"><a href="documentation_tools_flac.html#flac_options_preserve_modtime">--preserve-modtime</a></span> as in previous versions. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1805428&amp;group_id=13478&amp;atid=363478">SF #1805428</a>).</li>
<li>Allow MM:SS:FF and MM:SS.SS time formats in non-CD-DA cuesheets. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1947353&amp;group_id=13478&amp;atid=363478">SF #1947353</a>, <a href="https://sourceforge.net/tracker2/index.php?func=detail&amp;aid=2182432&amp;group_id=13478&amp;atid=113478">SF #2182432</a>)</li>
<li>The <span class="argument"><a href="documentation_tools_flac.html#flac_options_sector_align">--sector-align</a></span> option of <span class="commandname">flac</span> has been deprecated and may not exist in future versions. <a href="http://www.etree.org/shnutils/shntool/">shntool</a> provides similar functionality. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1805946&amp;group_id=13478&amp;atid=363478">SF #1805946</a>)</li> <li>The <span class="argument"><a href="documentation_tools_flac.html#flac_options_sector_align">--sector-align</a></span> option of <span class="commandname">flac</span> has been deprecated and may not exist in future versions. <a href="http://www.etree.org/shnutils/shntool/">shntool</a> provides similar functionality. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1805946&amp;group_id=13478&amp;atid=363478">SF #1805946</a>)</li>
<li>Improved error message when user attempts to decode a non-FLAC file (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=2222789&amp;group_id=13478&amp;atid=113478">SF #2222789</a>).</li> <li>Improved error message when user attempts to decode a non-FLAC file (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=2222789&amp;group_id=13478&amp;atid=113478">SF #2222789</a>).</li>
<li>Fix bug where <span class="commandname">flac</span> was disallowing use of <span class="argument">--replay-gain</span> when encoding from stdin (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1840124&amp;group_id=13478&amp;atid=113478">SF #1840124</a>).</li> <li>Fix bug where <span class="commandname">flac</span> was disallowing use of <span class="argument">--replay-gain</span> when encoding from stdin (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1840124&amp;group_id=13478&amp;atid=113478">SF #1840124</a>).</li>
@@ -92,7 +94,7 @@
<li> <li>
metaflac: metaflac:
<ul> <ul>
<li>(none)</li> <li>Allow MM:SS:FF and MM:SS.SS time formats in non-CD-DA cuesheets. (<a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=1947353&amp;group_id=13478&amp;atid=363478">SF #1947353</a>, <a href="https://sourceforge.net/tracker2/index.php?func=detail&amp;aid=2182432&amp;group_id=13478&amp;atid=113478">SF #2182432</a>)</li>
</ul> </ul>
</li> </li>
<li> <li>

View File

@@ -31,7 +31,7 @@ extern "C" {
unsigned grabbag__cuesheet_msf_to_frame(unsigned minutes, unsigned seconds, unsigned frames); unsigned grabbag__cuesheet_msf_to_frame(unsigned minutes, unsigned seconds, unsigned frames);
void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minutes, unsigned *seconds, unsigned *frames); void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minutes, unsigned *seconds, unsigned *frames);
FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset); FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset);
void grabbag__cuesheet_emit(FILE *file, const FLAC__StreamMetadata *cuesheet, const char *file_reference); void grabbag__cuesheet_emit(FILE *file, const FLAC__StreamMetadata *cuesheet, const char *file_reference);

View File

@@ -162,7 +162,7 @@ static FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder,
static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors); static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors);
static void print_stats(const EncoderSession *encoder_session); static void print_stats(const EncoderSession *encoder_session);
static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status); static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status);
static void print_error_with_state(const EncoderSession *e, const char *message); static void print_error_with_state(const EncoderSession *e, const char *message);
@@ -1770,7 +1770,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
} }
} }
if(!parse_cuesheet(&static_metadata.cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors)) if(!parse_cuesheet(&static_metadata.cuesheet, options.cuesheet_filename, e->inbasefilename, sample_rate, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
return false; return false;
if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? static_metadata.cuesheet : 0, e)) { if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? static_metadata.cuesheet : 0, e)) {
@@ -2560,7 +2560,7 @@ void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__Strea
data->fatal_error = true; data->fatal_error = true;
} }
FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors) FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors)
{ {
FILE *f; FILE *f;
unsigned last_line_read; unsigned last_line_read;
@@ -2579,7 +2579,7 @@ FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_
return false; return false;
} }
*cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset); *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, sample_rate, is_cdda, lead_out_offset);
fclose(f); fclose(f);

View File

@@ -42,6 +42,9 @@
#include <stdio.h> #include <stdio.h>
#endif #endif
/* OPT: #undef'ing this may improve the speed on some architectures */
#define FLAC__LPC_UNROLLED_FILTER_LOOPS
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef M_LN2 #ifndef M_LN2
@@ -49,9 +52,6 @@
#define M_LN2 0.69314718055994530942 #define M_LN2 0.69314718055994530942
#endif #endif
/* OPT: #undef'ing this may improve the speed on some architectures */
#define FLAC__LPC_UNROLLED_FILTER_LOOPS
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len)
{ {

View File

@@ -29,7 +29,7 @@
#include "share/grabbag.h" #include "share/grabbag.h"
#include "operations_shorthand.h" #include "operations_shorthand.h"
static FLAC__bool import_cs_from(const char *filename, FLAC__StreamMetadata **cuesheet, const char *cs_filename, FLAC__bool *needs_write, FLAC__uint64 lead_out_offset, FLAC__bool is_cdda, Argument_AddSeekpoint *add_seekpoint_link); static FLAC__bool import_cs_from(const char *filename, FLAC__StreamMetadata **cuesheet, const char *cs_filename, FLAC__bool *needs_write, FLAC__uint64 lead_out_offset, unsigned sample_rate, FLAC__bool is_cdda, Argument_AddSeekpoint *add_seekpoint_link);
static FLAC__bool export_cs_to(const char *filename, const FLAC__StreamMetadata *cuesheet, const char *cs_filename); static FLAC__bool export_cs_to(const char *filename, const FLAC__StreamMetadata *cuesheet, const char *cs_filename);
FLAC__bool do_shorthand_operation__cuesheet(const char *filename, FLAC__Metadata_Chain *chain, const Operation *operation, FLAC__bool *needs_write) FLAC__bool do_shorthand_operation__cuesheet(const char *filename, FLAC__Metadata_Chain *chain, const Operation *operation, FLAC__bool *needs_write)
@@ -39,6 +39,7 @@ FLAC__bool do_shorthand_operation__cuesheet(const char *filename, FLAC__Metadata
FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new(); FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new();
FLAC__uint64 lead_out_offset = 0; FLAC__uint64 lead_out_offset = 0;
FLAC__bool is_cdda = false; FLAC__bool is_cdda = false;
unsigned sample_rate = 0;
if(0 == iterator) if(0 == iterator)
die("out of memory allocating iterator"); die("out of memory allocating iterator");
@@ -54,7 +55,8 @@ FLAC__bool do_shorthand_operation__cuesheet(const char *filename, FLAC__Metadata
FLAC__metadata_iterator_delete(iterator); FLAC__metadata_iterator_delete(iterator);
return false; return false;
} }
is_cdda = (block->data.stream_info.channels == 1 || block->data.stream_info.channels == 2) && (block->data.stream_info.bits_per_sample == 16) && (block->data.stream_info.sample_rate == 44100); sample_rate = block->data.stream_info.sample_rate;
is_cdda = (block->data.stream_info.channels == 1 || block->data.stream_info.channels == 2) && (block->data.stream_info.bits_per_sample == 16) && (sample_rate == 44100);
} }
else if(block->type == FLAC__METADATA_TYPE_CUESHEET) else if(block->type == FLAC__METADATA_TYPE_CUESHEET)
cuesheet = block; cuesheet = block;
@@ -73,7 +75,7 @@ FLAC__bool do_shorthand_operation__cuesheet(const char *filename, FLAC__Metadata
ok = false; ok = false;
} }
else { else {
ok = import_cs_from(filename, &cuesheet, operation->argument.import_cuesheet_from.filename, needs_write, lead_out_offset, is_cdda, operation->argument.import_cuesheet_from.add_seekpoint_link); ok = import_cs_from(filename, &cuesheet, operation->argument.import_cuesheet_from.filename, needs_write, lead_out_offset, sample_rate, is_cdda, operation->argument.import_cuesheet_from.add_seekpoint_link);
if(ok) { if(ok) {
/* append CUESHEET block */ /* append CUESHEET block */
while(FLAC__metadata_iterator_next(iterator)) while(FLAC__metadata_iterator_next(iterator))
@@ -108,7 +110,7 @@ FLAC__bool do_shorthand_operation__cuesheet(const char *filename, FLAC__Metadata
* local routines * local routines
*/ */
FLAC__bool import_cs_from(const char *filename, FLAC__StreamMetadata **cuesheet, const char *cs_filename, FLAC__bool *needs_write, FLAC__uint64 lead_out_offset, FLAC__bool is_cdda, Argument_AddSeekpoint *add_seekpoint_link) FLAC__bool import_cs_from(const char *filename, FLAC__StreamMetadata **cuesheet, const char *cs_filename, FLAC__bool *needs_write, FLAC__uint64 lead_out_offset, unsigned sample_rate, FLAC__bool is_cdda, Argument_AddSeekpoint *add_seekpoint_link)
{ {
FILE *f; FILE *f;
const char *error_message; const char *error_message;
@@ -129,7 +131,7 @@ FLAC__bool import_cs_from(const char *filename, FLAC__StreamMetadata **cuesheet,
return false; return false;
} }
*cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset); *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, sample_rate, is_cdda, lead_out_offset);
if(f != stdin) if(f != stdin)
fclose(f); fclose(f);

View File

@@ -76,10 +76,11 @@ static FLAC__int64 local__parse_int64_(const char *s)
return ret; return ret;
} }
/* accept '[0-9]+:[0-9][0-9]?:[0-9][0-9]?', but max second of 59 and max frame of 74, e.g. 0:0:0, 123:45:67 /* accept minute:second:frame syntax of '[0-9]+:[0-9][0-9]?:[0-9][0-9]?', but max second of 59 and max frame of 74, e.g. 0:0:0, 123:45:67
* return sample number or <0 for error * return sample number or <0 for error
* WATCHOUT: if sample rate is not evenly divisible by 75, the resulting sample number will be approximate
*/ */
static FLAC__int64 local__parse_msf_(const char *s) static FLAC__int64 local__parse_msf_(const char *s, unsigned sample_rate)
{ {
FLAC__int64 ret, field; FLAC__int64 ret, field;
char c; char c;
@@ -96,7 +97,7 @@ static FLAC__int64 local__parse_msf_(const char *s)
return -1; return -1;
} }
ret = field * 60 * 44100; ret = field * 60 * sample_rate;
c = *s++; c = *s++;
if(c >= '0' && c <= '9') if(c >= '0' && c <= '9')
@@ -117,7 +118,7 @@ static FLAC__int64 local__parse_msf_(const char *s)
if(field >= 60) if(field >= 60)
return -1; return -1;
ret += field * 44100; ret += field * sample_rate;
c = *s++; c = *s++;
if(c >= '0' && c <= '9') if(c >= '0' && c <= '9')
@@ -139,7 +140,45 @@ static FLAC__int64 local__parse_msf_(const char *s)
if(field >= 75) if(field >= 75)
return -1; return -1;
ret += field * (44100 / 75); ret += field * (sample_rate / 75);
return ret;
}
/* accept minute:second syntax of '[0-9]+:[0-9][0-9]?{,.[0-9]+}', but second < 60, e.g. 0:0.0, 3:5, 15:31.731
* return sample number or <0 for error
* WATCHOUT: depending on the sample rate, the resulting sample number may be approximate with fractional seconds
*/
static FLAC__int64 local__parse_ms_(const char *s, unsigned sample_rate)
{
FLAC__int64 ret, field;
double x;
char c, *end;
c = *s++;
if(c >= '0' && c <= '9')
field = (c - '0');
else
return -1;
while(':' != (c = *s++)) {
if(c >= '0' && c <= '9')
field = field * 10 + (c - '0');
else
return -1;
}
ret = field * 60 * sample_rate;
s++; /* skip the ':' */
if(strspn(s, "0123456789.") != strlen(s))
return -1;
x = strtod(s, &end);
if(*end || end == s)
return -1;
if(x < 0.0 || x >= 60.0)
return -1;
ret += (FLAC__int64)(x * sample_rate);
return ret; return ret;
} }
@@ -198,7 +237,7 @@ static char *local__get_field_(char **s, FLAC__bool allow_quotes)
return p; return p;
} }
static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__StreamMetadata *cuesheet, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset) static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__StreamMetadata *cuesheet, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
{ {
#if defined _MSC_VER || defined __MINGW32__ || defined __EMX__ #if defined _MSC_VER || defined __MINGW32__ || defined __EMX__
#define FLAC__STRCASECMP stricmp #define FLAC__STRCASECMP stricmp
@@ -212,6 +251,13 @@ static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message,
FLAC__bool disc_has_catalog = false, track_has_flags = false, track_has_isrc = false, has_forced_leadout = false; FLAC__bool disc_has_catalog = false, track_has_flags = false, track_has_isrc = false, has_forced_leadout = false;
FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet; FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
FLAC__ASSERT(!is_cdda || sample_rate == 44100);
/* double protection */
if(is_cdda && sample_rate != 44100) {
*error_message = "CD-DA cuesheet only allowed with 44.1kHz sample rate";
return false;
}
cs->lead_in = is_cdda? 2 * 44100 /* The default lead-in size for CD-DA */ : 0; cs->lead_in = is_cdda? 2 * 44100 /* The default lead-in size for CD-DA */ : 0;
cs->is_cd = is_cdda; cs->is_cd = is_cdda;
@@ -302,18 +348,28 @@ static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message,
*error_message = "INDEX is missing an offset after the index number"; *error_message = "INDEX is missing an offset after the index number";
return false; return false;
} }
xx = local__parse_msf_(field); /* first parse as minute:second:frame format */
xx = local__parse_msf_(field, sample_rate);
if(xx < 0) { if(xx < 0) {
/* CD-DA must use only MM:SS:FF format */
if(is_cdda) { if(is_cdda) {
*error_message = "illegal INDEX offset (not of the form MM:SS:FF)"; *error_message = "illegal INDEX offset (not of the form MM:SS:FF)";
return false; return false;
} }
/* as an extension for non-CD-DA we allow MM:SS.SS or raw sample number */
xx = local__parse_ms_(field, sample_rate);
if(xx < 0) {
xx = local__parse_int64_(field); xx = local__parse_int64_(field);
if(xx < 0) { if(xx < 0) {
*error_message = "illegal INDEX offset"; *error_message = "illegal INDEX offset";
return false; return false;
} }
} }
}
else if(sample_rate % 75) {
*error_message = "illegal INDEX offset (MM:SS:FF form not allowed if sample rate is not a multiple of 75)";
return false;
}
if(is_cdda && cs->num_tracks == 1 && cs->tracks[0].num_indices == 0 && xx != 0) { if(is_cdda && cs->num_tracks == 1 && cs->tracks[0].num_indices == 0 && xx != 0) {
*error_message = "first INDEX of first TRACK must have an offset of 00:00:00"; *error_message = "first INDEX of first TRACK must have an offset of 00:00:00";
return false; return false;
@@ -533,7 +589,7 @@ static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message,
#undef FLAC__STRCASECMP #undef FLAC__STRCASECMP
} }
FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset) FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
{ {
FLAC__StreamMetadata *cuesheet; FLAC__StreamMetadata *cuesheet;
@@ -549,7 +605,7 @@ FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_mes
return 0; return 0;
} }
if(!local__cuesheet_parse_(file, error_message, last_line_read, cuesheet, is_cdda, lead_out_offset)) { if(!local__cuesheet_parse_(file, error_message, last_line_read, cuesheet, sample_rate, is_cdda, lead_out_offset)) {
FLAC__metadata_object_delete(cuesheet); FLAC__metadata_object_delete(cuesheet);
return 0; return 0;
} }

View File

@@ -28,7 +28,7 @@
#include "FLAC/metadata.h" #include "FLAC/metadata.h"
#include "share/grabbag.h" #include "share/grabbag.h"
static int do_cuesheet(const char *infilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset) static int do_cuesheet(const char *infilename, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
{ {
FILE *fin, *fout; FILE *fin, *fout;
const char *error_message; const char *error_message;
@@ -48,7 +48,7 @@ static int do_cuesheet(const char *infilename, FLAC__bool is_cdda, FLAC__uint64
fprintf(stderr, "can't open file %s for reading: %s\n", infilename, strerror(errno)); fprintf(stderr, "can't open file %s for reading: %s\n", infilename, strerror(errno));
return 255; return 255;
} }
if(0 != (cuesheet = grabbag__cuesheet_parse(fin, &error_message, &last_line_read, is_cdda, lead_out_offset))) { if(0 != (cuesheet = grabbag__cuesheet_parse(fin, &error_message, &last_line_read, sample_rate, is_cdda, lead_out_offset))) {
if(fin != stdin) if(fin != stdin)
fclose(fin); fclose(fin);
} }
@@ -80,7 +80,7 @@ static int do_cuesheet(const char *infilename, FLAC__bool is_cdda, FLAC__uint64
fprintf(stderr, "can't open file %s for reading: %s\n", tmpfilename, strerror(errno)); fprintf(stderr, "can't open file %s for reading: %s\n", tmpfilename, strerror(errno));
return 255; return 255;
} }
if(0 != (cuesheet = grabbag__cuesheet_parse(fin, &error_message, &last_line_read, is_cdda, lead_out_offset))) { if(0 != (cuesheet = grabbag__cuesheet_parse(fin, &error_message, &last_line_read, sample_rate, is_cdda, lead_out_offset))) {
if(fin != stdin) if(fin != stdin)
fclose(fin); fclose(fin);
} }
@@ -111,28 +111,32 @@ static int do_cuesheet(const char *infilename, FLAC__bool is_cdda, FLAC__uint64
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
FLAC__uint64 lead_out_offset; FLAC__uint64 lead_out_offset;
unsigned sample_rate;
FLAC__bool is_cdda = false; FLAC__bool is_cdda = false;
const char *usage = "usage: test_cuesheet cuesheet_file lead_out_offset [ cdda ]\n"; const char *usage = "usage: test_cuesheet cuesheet_file lead_out_offset [ [ sample_rate ] cdda ]\n";
if(argc > 1 && 0 == strcmp(argv[1], "-h")) { if(argc > 1 && 0 == strcmp(argv[1], "-h")) {
printf(usage); printf(usage);
return 0; return 0;
} }
if(argc < 3 || argc > 4) { if(argc < 3 || argc > 5) {
fprintf(stderr, usage); fprintf(stderr, usage);
return 255; return 255;
} }
lead_out_offset = (FLAC__uint64)strtoul(argv[2], 0, 10); lead_out_offset = (FLAC__uint64)strtoul(argv[2], 0, 10);
if(argc == 4) { if(argc >= 4) {
if(0 == strcmp(argv[3], "cdda")) sample_rate = (unsigned)atoi(argv[3]);
if(argc >= 5) {
if(0 == strcmp(argv[4], "cdda"))
is_cdda = true; is_cdda = true;
else { else {
fprintf(stderr, usage); fprintf(stderr, usage);
return 255; return 255;
} }
} }
}
return do_cuesheet(argv[1], is_cdda, lead_out_offset); return do_cuesheet(argv[1], sample_rate, is_cdda, lead_out_offset);
} }

View File

@@ -111,7 +111,7 @@ rm -f $log
# #
for cuesheet in $bad_cuesheets ; do for cuesheet in $bad_cuesheets ; do
echo "NEGATIVE $cuesheet" >> $log 2>&1 echo "NEGATIVE $cuesheet" >> $log 2>&1
run_test_cuesheet $cuesheet $good_leadout cdda >> $log 2>&1 run_test_cuesheet $cuesheet $good_leadout 44100 cdda >> $log 2>&1
exit_code=$? exit_code=$?
if [ "$exit_code" = 255 ] ; then if [ "$exit_code" = 255 ] ; then
die "Error: test script is broken" die "Error: test script is broken"
@@ -126,7 +126,7 @@ done
# #
for cuesheet in $good_cuesheets ; do for cuesheet in $good_cuesheets ; do
echo "POSITIVE $cuesheet" >> $log 2>&1 echo "POSITIVE $cuesheet" >> $log 2>&1
run_test_cuesheet $cuesheet $good_leadout cdda >> $log 2>&1 run_test_cuesheet $cuesheet $good_leadout 44100 cdda >> $log 2>&1
exit_code=$? exit_code=$?
if [ "$exit_code" = 255 ] ; then if [ "$exit_code" = 255 ] ; then
die "Error: test script is broken" die "Error: test script is broken"