Skip to content

Commit

Permalink
Improve console output of flac tool (#734)
Browse files Browse the repository at this point in the history
Fixes various cases of erratic behaviour (most notably output not
starting on the first character of a line). Also, some warnings
and errors now mark the location in the stream where this error
seems to have occured
  • Loading branch information
ktmf01 authored Aug 21, 2024
1 parent 192bf22 commit 8e6498d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
22 changes: 12 additions & 10 deletions src/flac/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1148,10 +1148,11 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
/* sanity-check the bits-per-sample */
if(decoder_session->bps) {
if(bps != decoder_session->bps) {
FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
if(decoder_session->got_stream_info)
flac__utils_printf(stderr, 1, "%s: ERROR, bits-per-sample is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, bps, decoder_session->bps);
flac__utils_printf_clear_stats(stderr, 1, "%s: ERROR, bits-per-sample is %u in frame starting at sample %" PRIu64 " but %u in STREAMINFO\n", decoder_session->inbasefilename, bps, frame->header.number.sample_number, decoder_session->bps);
else
flac__utils_printf(stderr, 1, "%s: ERROR, bits-per-sample is %u in this frame but %u in previous frames\n", decoder_session->inbasefilename, bps, decoder_session->bps);
flac__utils_printf_clear_stats(stderr, 1, "%s: ERROR, bits-per-sample is %u in frame starting at sample %" PRIu64 " but %u in previous frames\n", decoder_session->inbasefilename, bps, frame->header.number.sample_number, decoder_session->bps);
if(!decoder_session->continue_through_decode_errors)
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
else if(decoder_session->replaygain.apply) {
Expand All @@ -1165,18 +1166,19 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
FLAC__ASSERT(!decoder_session->got_stream_info);
decoder_session->bps = bps;
if(decoder_session->format == FORMAT_RAW && ((decoder_session->bps % 8) != 0 || decoder_session->bps < 4)) {
flac__utils_printf(stderr, 1, "%s: ERROR: bits per sample is %u, must be 8/16/24/32 for raw format output\n", decoder_session->inbasefilename, decoder_session->bps);
flac__utils_printf_clear_stats(stderr, 1, "%s: ERROR: bits per sample is %u, must be 8/16/24/32 for raw format output\n", decoder_session->inbasefilename, decoder_session->bps);
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
}

/* sanity-check the #channels */
if(decoder_session->channels) {
if(channels != decoder_session->channels) {
FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
if(decoder_session->got_stream_info)
flac__utils_printf(stderr, 1, "%s: ERROR, channels is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, channels, decoder_session->channels);
flac__utils_printf_clear_stats(stderr, 1, "%s: ERROR, channels is %u in frame starting at sample %" PRIu64 " but %u in STREAMINFO\n", decoder_session->inbasefilename, channels, frame->header.number.sample_number, decoder_session->channels);
else
flac__utils_printf(stderr, 1, "%s: ERROR, channels is %u in this frame but %u in previous frames\n", decoder_session->inbasefilename, channels, decoder_session->channels);
flac__utils_printf_clear_stats(stderr, 1, "%s: ERROR, channels is %u in frame starting at sample %" PRIu64 " but %u in previous frames\n", decoder_session->inbasefilename, channels, frame->header.number.sample_number, decoder_session->channels);
if(!decoder_session->continue_through_decode_errors)
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
Expand All @@ -1190,10 +1192,11 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
/* sanity-check the sample rate */
if(decoder_session->sample_rate < UINT32_MAX) {
if(frame->header.sample_rate != decoder_session->sample_rate) {
FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
if(decoder_session->got_stream_info)
flac__utils_printf(stderr, 1, "%s: ERROR, sample rate is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, frame->header.sample_rate, decoder_session->sample_rate);
flac__utils_printf_clear_stats(stderr, 1, "%s: ERROR, sample rate is %u in frame starting at sample %" PRIu64 " but %u in STREAMINFO\n", decoder_session->inbasefilename, frame->header.sample_rate, frame->header.number.sample_number, decoder_session->sample_rate);
else
flac__utils_printf(stderr, 1, "%s: ERROR, sample rate is %u in this frame but %u in previous frames\n", decoder_session->inbasefilename, frame->header.sample_rate, decoder_session->sample_rate);
flac__utils_printf_clear_stats(stderr, 1, "%s: ERROR, sample rate is %u in frame starting at sample %" PRIu64 " but %u in previous frames\n", decoder_session->inbasefilename, frame->header.sample_rate, frame->header.number.sample_number, decoder_session->sample_rate);
if(!decoder_session->continue_through_decode_errors)
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
Expand Down Expand Up @@ -1257,7 +1260,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
if(decoder_session->prev_frameheader.number.sample_number +
decoder_session->prev_frameheader.blocksize !=
frame->header.number.sample_number) {
flac__utils_printf(stderr, 1, "%s: WARNING: sample or frame number does not increase correctly, file might not be seekable\n", decoder_session->inbasefilename);
flac__utils_printf_clear_stats(stderr, 1, "%s: WARNING: sample or frame number does not increase correctly (%" PRIu64 " samples have been decoded), file might not be seekable\n", decoder_session->inbasefilename, decoder_session->samples_processed);
if(decoder_session->treat_warnings_as_errors) {
decoder_session->abort_flag = true;
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
Expand Down Expand Up @@ -1629,8 +1632,7 @@ void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderError
DecoderSession *decoder_session = (DecoderSession*)client_data;
(void)decoder;
if(!decoder_session->error_callback_suppress_messages) {
stats_print_name(1, decoder_session->inbasefilename);
flac__utils_printf(stderr, 1, "*** Got error code %d:%s\n", status, FLAC__StreamDecoderErrorStatusString[status]);
flac__utils_printf_clear_stats(stderr, 1, "%s: *** Got error code %d:%s after processing %" PRIu64 " samples\n", decoder_session->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status], decoder_session->samples_processed);
}
if(!decoder_session->continue_through_decode_errors) {
/* if we got a sync error while looking for metadata, either it's not a FLAC file (more likely) or the file is corrupted */
Expand Down
27 changes: 27 additions & 0 deletions src/flac/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ size_t strlen_console(const char *text)
void stats_new_file(void)
{
is_name_printed = false;
stats_char_count = 0;
}

void stats_clear(void)
Expand Down Expand Up @@ -276,6 +277,32 @@ void stats_print_info(int level, const char *format, ...)
}
}

void flac__utils_printf_clear_stats(FILE *stream, int level, const char *format, ...)
{
if(flac__utils_verbosity_ >= level) {
va_list args;

FLAC__ASSERT(0 != format);

if(is_name_printed || stats_char_count > 0) {
flac_fprintf(stderr,"\r");
stats_char_count = 0;
is_name_printed = false;
}

va_start(args, format);

(void) flac_vfprintf(stream, format, args);

va_end(args);

#ifdef _MSC_VER
if(stream == stderr)
fflush(stream); /* for some reason stderr is buffered in at least some if not all MSC libs */
#endif
}
}

#ifdef FLAC__VALGRIND_TESTING
size_t flac__utils_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
Expand Down
1 change: 1 addition & 0 deletions src/flac/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void stats_new_file(void);
void stats_clear(void);
void stats_print_name(int level, const char *name);
void stats_print_info(int level, const char *format, ...);
void flac__utils_printf_clear_stats(FILE *stream, int level, const char *format, ...);

FLAC__bool flac__utils_check_empty_skip_until_specification(utils__SkipUntilSpecification *spec);
FLAC__bool flac__utils_parse_skip_until_specification(const char *s, utils__SkipUntilSpecification *spec);
Expand Down

0 comments on commit 8e6498d

Please sign in to comment.