initial import
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 16 Mar 2001 22:01:06 +0000 (22:01 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 16 Mar 2001 22:01:06 +0000 (22:01 +0000)
src/flac/analyze.c [new file with mode: 0644]
src/flac/analyze.h [new file with mode: 0644]

diff --git a/src/flac/analyze.c b/src/flac/analyze.c
new file mode 100644 (file)
index 0000000..5ae7856
--- /dev/null
@@ -0,0 +1,152 @@
+/* flac - Command-line FLAC encoder/decoder
+ * Copyright (C) 2000,2001  Josh Coalson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "FLAC/all.h"
+#include "analyze.h"
+
+typedef struct {
+       int32 residual;
+       unsigned count;
+} pair_t;
+
+static pair_t super_buckets[FLAC__MAX_BLOCK_SIZE];
+static unsigned nsuper_buckets;
+
+static void update_buckets(int32 residual, pair_t *buckets, unsigned *nbuckets, unsigned incr);
+static bool print_buckets(const pair_t buckets[], const unsigned nbuckets, const char *filename);
+
+void analyze_init()
+{
+       nsuper_buckets = 0;
+}
+
+void analyze_frame(const FLAC__Frame *frame, unsigned frame_number, analysis_options aopts, FILE *fout)
+{
+       const unsigned channels = frame->header.channels;
+       char outfilename[1024];
+       pair_t buckets[FLAC__MAX_BLOCK_SIZE];
+       unsigned i, channel, nbuckets;
+
+       /* do the human-readable part first */
+       fprintf(fout, "frame=%u\tblocksize=%u\tsample_rate=%u\tchannels=%u\tchannel_assignment=%s\n", frame_number, frame->header.blocksize, frame->header.sample_rate, 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 */
+                               for(i = 0; i < subframe->data.fixed.order; i++)
+                                       fprintf(fout, "\t\twarmup[%u]=%d\n", i, subframe->data.fixed.warmup[i]);
+                               if(aopts.do_residual_text) {
+                                       for(i = 0; i < frame->header.blocksize-subframe->data.fixed.order; i++)
+                                               fprintf(fout, "\t\tresidual[%u]=%d\n", i, subframe->data.fixed.residual[i]);
+                               }
+                               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 */
+                               for(i = 0; i < subframe->data.lpc.order; i++)
+                                       fprintf(fout, "\t\twarmup[%u]=%d\n", i, subframe->data.lpc.warmup[i]);
+                               if(aopts.do_residual_text) {
+                                       for(i = 0; i < frame->header.blocksize-subframe->data.lpc.order; i++)
+                                               fprintf(fout, "\t\tresidual[%u]=%d\n", i, subframe->data.lpc.residual[i]);
+                               }
+                               break;
+                       case FLAC__SUBFRAME_TYPE_VERBATIM:
+                               fprintf(fout, "\n");
+                               break;
+               }
+       }
+
+       /* now do the residual distributions if requested */
+       if(aopts.do_residual_gnuplot) {
+               for(channel = 0; channel < channels; channel++) {
+                       const FLAC__Subframe *subframe = frame->subframes+channel;
+
+                       nbuckets = 0;
+
+                       switch(subframe->type) {
+                               case FLAC__SUBFRAME_TYPE_FIXED:
+                                       for(i = 0; i < frame->header.blocksize-subframe->data.fixed.order; i++)
+                                               update_buckets(subframe->data.fixed.residual[i], buckets, &nbuckets, 1);
+                                       break;
+                               case FLAC__SUBFRAME_TYPE_LPC:
+                                       for(i = 0; i < frame->header.blocksize-subframe->data.lpc.order; i++)
+                                               update_buckets(subframe->data.lpc.residual[i], buckets, &nbuckets, 1);
+                                       break;
+                               default:
+                                       break;
+                       }
+
+                       /* update super_buckets */
+                       for(i = 0; i < nbuckets; i++) {
+                               update_buckets(buckets[i].residual, super_buckets, &nsuper_buckets, buckets[i].count);
+                       }
+
+                       /* write the subframe */
+                       sprintf(outfilename, "f%06u.s%u.gp", frame_number, channel);
+                       (void)print_buckets(buckets, nbuckets, outfilename);
+               }
+       }
+}
+
+void analyze_finish()
+{
+       (void)print_buckets(super_buckets, nsuper_buckets, "all");
+}
+
+void update_buckets(int32 residual, pair_t *buckets, unsigned *nbuckets, unsigned incr)
+{
+       unsigned i;
+
+       for(i = 0; i < *nbuckets; i++) {
+               if(buckets[i].residual == residual) {
+                       buckets[i].count += incr;
+                       return;
+               }
+       }
+       buckets[*nbuckets].residual = residual;
+       buckets[*nbuckets].count = incr;
+       (*nbuckets)++;
+}
+
+bool print_buckets(const pair_t buckets[], const unsigned nbuckets, const char *filename)
+{
+       FILE *outfile;
+       unsigned i;
+
+       outfile = fopen(filename, "w");
+
+       if(0 == outfile) {
+               fprintf(stderr, "ERROR opening %s\n", filename);
+               return false;
+       }
+
+       for(i = 0; i < nbuckets; i++) {
+               fprintf(outfile, "%d %u\n", buckets[i].residual, buckets[i].count);
+       }
+
+       fclose(outfile);
+       return true;
+}
diff --git a/src/flac/analyze.h b/src/flac/analyze.h
new file mode 100644 (file)
index 0000000..24a791c
--- /dev/null
@@ -0,0 +1,31 @@
+/* flac - Command-line FLAC encoder/decoder
+ * Copyright (C) 2000,2001  Josh Coalson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef flac__analyze_h
+#define flac__analyze_h
+
+typedef struct {
+       bool do_residual_text;
+       bool do_residual_gnuplot;
+} analysis_options;
+
+void analyze_init();
+void analyze_frame(const FLAC__Frame *frame, unsigned frame_number, analysis_options aopts, FILE *fout);
+void analyze_finish();
+
+#endif