add new analyze mode
authorJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 24 Jan 2001 00:42:41 +0000 (00:42 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 24 Jan 2001 00:42:41 +0000 (00:42 +0000)
src/flac/decode.c
src/flac/decode.h
src/flac/main.c

index e501643..a0248a9 100644 (file)
@@ -22,6 +22,7 @@
 #else
 # include <unistd.h>
 #endif
+#include <assert.h> /* for FILE */
 #include <stdio.h> /* for FILE */
 #include <string.h> /* for strcmp() */
 #include "FLAC/all.h"
@@ -30,6 +31,7 @@
 typedef struct {
        FILE *fout;
        bool abort_flag;
+       bool analysis_mode;
        bool test_only;
        bool is_wave_out;
        bool is_big_endian;
@@ -56,13 +58,14 @@ static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__Stre
 static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
 static void print_stats(const stream_info_struct *stream_info);
 
-int decode_wav(const char *infile, const char *outfile, bool verbose, uint64 skip)
+int decode_wav(const char *infile, const char *outfile, bool analysis_mode, bool verbose, uint64 skip)
 {
        bool md5_failure = false;
        stream_info_struct stream_info;
 
        decoder = 0;
        stream_info.abort_flag = false;
+       stream_info.analysis_mode = analysis_mode;
        stream_info.test_only = (outfile == 0);
        stream_info.is_wave_out = true;
        stream_info.verbose = verbose;
@@ -70,6 +73,8 @@ int decode_wav(const char *infile, const char *outfile, bool verbose, uint64 ski
        stream_info.samples_processed = 0;
        stream_info.frame_counter = 0;
 
+       assert(!(test_only && analysis_mode));
+
        if(!stream_info.test_only) {
                if(0 == strcmp(outfile, "-")) {
                        stream_info.fout = stdout;
@@ -151,13 +156,14 @@ wav_abort_:
        return 1;
 }
 
-int decode_raw(const char *infile, const char *outfile, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples)
+int decode_raw(const char *infile, const char *outfile, bool analysis_mode, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples)
 {
        bool md5_failure = false;
        stream_info_struct stream_info;
 
        decoder = 0;
        stream_info.abort_flag = false;
+       stream_info.analysis_mode = analysis_mode;
        stream_info.test_only = (outfile == 0);
        stream_info.is_wave_out = false;
        stream_info.is_big_endian = is_big_endian;
@@ -167,6 +173,8 @@ int decode_raw(const char *infile, const char *outfile, bool verbose, uint64 ski
        stream_info.samples_processed = 0;
        stream_info.frame_counter = 0;
 
+       assert(!(test_only && analysis_mode));
+
        if(!stream_info.test_only) {
                if(0 == strcmp(outfile, "-")) {
                        stream_info.fout = stdout;
@@ -314,7 +322,28 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder,
        if(stream_info->verbose && !(stream_info->frame_counter & 0x1f))
                print_stats(stream_info);
 
-       if(!stream_info->test_only) {
+       if(stream_info->analysis_mode) {
+               fprintf(fout, "frame=%u\tblocksize=%u\tsample_rate=%u\tchannels=%u\tchannel_assignment=%s\n", stream_info->frame_counter-1, frame->header.blocksize, frame->header.sample_rate, frame->header.channels, FLAC__ChannelAssignmentString[frame->header.channel_assignment]);
+               for(channel = 0; channel < channels; channel++) {
+                       const FLAC__Subframe *subframe = frame->subframes+channel;
+                       fprintf(fout, "\tsubframe=%u\ttype=%s", channel, FLAC__SubframeTypeString[subframe->type]);
+                       switch(subframe->type) {
+                               case FLAC__SUBFRAME_TYPE_CONSTANT:
+                                       fprintf(fout, "\tvalue=%d\n", subframe->data.constant.value);
+                                       break;
+                               case FLAC__SUBFRAME_TYPE_FIXED:
+                                       fprintf(fout, "\torder=%u\tpartition_order=%u\n", subframe->data.fixed.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order); /*@@@ assumes method is partitioned-rice */
+                                       break;
+                               case FLAC__SUBFRAME_TYPE_LPC:
+                                       fprintf(fout, "\torder=%u\tpartition_order=%u\tqlp_coeff_precision=%u\tquantization_level=%d\n", subframe->data.lpc.order, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order, subframe->data.lpc.qlp_coeff_precision, subframe->data.lpc.quantization_level); /*@@@ assumes method is partitioned-rice */
+                                       break;
+                               case FLAC__SUBFRAME_TYPE_VERBATIM:
+                                       fprintf(fout, "\n");
+                                       break;
+                       }
+               }
+       }
+       else if(!stream_info->test_only) {
                if(bps == 8) {
                        if(is_unsigned_samples) {
                                for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
@@ -372,7 +401,7 @@ void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaD
                }
 
                /* write the WAVE headers if necessary */
-               if(!stream_info->test_only && stream_info->is_wave_out) {
+               if(!stream_info->analysis_mode && !stream_info->test_only && stream_info->is_wave_out) {
                        uint64 data_size = stream_info->total_samples * stream_info->channels * ((stream_info->bps+7)/8);
                        if(data_size >= 0xFFFFFFDC) {
                                fprintf(stderr, "ERROR: stream is too big for a wave file\n");
@@ -407,7 +436,7 @@ void print_stats(const stream_info_struct *stream_info)
 {
        if(stream_info->verbose) {
                printf("\r%s %u of %u samples, %6.2f%% complete",
-                       stream_info->test_only? "tested" : "wrote",
+                       stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
                        (unsigned)stream_info->samples_processed,
                        (unsigned)stream_info->total_samples,
 #ifdef _MSC_VER
index 60879fd..b698d34 100644 (file)
@@ -20,7 +20,7 @@
 #define flac__decode_h
 
 /* outfile == 0 => test only */
-int decode_wav(const char *infile, const char *outfile, bool verbose, uint64 skip);
-int decode_raw(const char *infile, const char *outfile, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples);
+int decode_wav(const char *infile, const char *outfile, bool analysis_mode, bool verbose, uint64 skip);
+int decode_raw(const char *infile, const char *outfile, bool analysis_mode, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples);
 
 #endif
index ebcfd5e..8d19736 100644 (file)
@@ -31,7 +31,7 @@ static int usage(const char *message, ...);
 int main(int argc, char *argv[])
 {
        int i;
-       bool verify = false, verbose = true, lax = false, mode_decode = false, test_only = false;
+       bool verify = false, verbose = true, lax = false, mode_decode = false, test_only = false, analyze = false;
        bool do_mid_side = true, do_exhaustive_model_search = false, do_qlp_coeff_prec_search = false;
        unsigned max_lpc_order = 8;
        unsigned qlp_coeff_precision = 0;
@@ -49,6 +49,10 @@ int main(int argc, char *argv[])
                        break;
                if(0 == strcmp(argv[i], "-d"))
                        mode_decode = true;
+               else if(0 == strcmp(argv[i], "-a")) {
+                       mode_decode = true;
+                       analyze = true;
+               }
                else if(0 == strcmp(argv[i], "-t")) {
                        mode_decode = true;
                        test_only = true;
@@ -200,7 +204,7 @@ int main(int argc, char *argv[])
                        if(skip > 0)
                                return usage("ERROR: --skip is not allowed in test mode\n");
                }
-               else {
+               else if(!analyze) {
                        if(format_is_wave < 0) {
                                if(strstr(argv[i+1], ".wav") == argv[i+1] + (strlen(argv[i+1]) - strlen(".wav")))
                                        format_is_wave = true;
@@ -257,9 +261,9 @@ int main(int argc, char *argv[])
 
        if(mode_decode)
                if(format_is_wave)
-                       return decode_wav(argv[i], test_only? 0 : argv[i+1], verbose, skip);
+                       return decode_wav(argv[i], test_only? 0 : argv[i+1], analyze, verbose, skip);
                else
-                       return decode_raw(argv[i], test_only? 0 : argv[i+1], verbose, skip, format_is_big_endian, format_is_unsigned_samples);
+                       return decode_raw(argv[i], test_only? 0 : argv[i+1], analyze, verbose, skip, format_is_big_endian, format_is_unsigned_samples);
        else
                if(format_is_wave)
                        return encode_wav(argv[i], argv[i+1], verbose, skip, verify, lax, do_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, rice_optimization_level, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision);
@@ -305,7 +309,7 @@ int usage(const char *message, ...)
        printf("For encoding:\n");
        printf("  infile may be a PCM RIFF WAVE file or raw samples\n");
        printf("  outfile will be in FLAC format\n");
-       printf("For decoding, the reverse will be true\n");
+       printf("For decoding, the reverse is be true\n");
        printf("\n");
        printf("infile may be - for stdin, outfile may be - for stdout\n");
        printf("\n");