Commit 967b467c authored by Josh Coalson's avatar Josh Coalson
Browse files

add new analyze mode

parent 75d0a0be
......@@ -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
......
......@@ -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
......@@ -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");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment