shithub: sox

Download patch

ref: 7438be46b4c1874cda7f1c23d67427bd9ad42b27
parent: 72751915968c8dbcef0252c5fda7a07b4eb4026e
author: robs <robs>
date: Thu Jan 24 15:06:28 EST 2008

Fix and support for FLAC 1.2.x; further fixes needed in sox.c tho'

--- a/src/flac.c
+++ b/src/flac.c
@@ -44,7 +44,9 @@
 #define FLAC__stream_decoder_seek_absolute FLAC__file_decoder_seek_absolute
 #endif
 
+#define MAX_COMPRESSION 8
 
+
 typedef struct {
   /* Info: */
   unsigned bits_per_sample;
@@ -309,7 +311,19 @@
 {
   Encoder * encoder = (Encoder *) ft->priv;
   FLAC__StreamEncoderState status;
+  unsigned compression_level = MAX_COMPRESSION; /* Default to "best" */
 
+  if (ft->signal.compression != HUGE_VAL) {
+    compression_level = ft->signal.compression;
+    if (compression_level != ft->signal.compression || 
+        compression_level > MAX_COMPRESSION) {
+      sox_fail_errno(ft, SOX_EINVAL,
+                 "FLAC compression level must be a whole number from 0 to %i",
+                 MAX_COMPRESSION);
+      return SOX_EOF;
+    }
+  }
+
   memset(encoder, 0, sizeof(*encoder));
   encoder->flac = FLAC__stream_encoder_new();
   if (encoder->flac == NULL) {
@@ -318,7 +332,36 @@
   }
   encoder->decoded_samples = xmalloc(sox_globals.bufsiz * sizeof(FLAC__int32));
 
-  {     /* Select and set FLAC encoder options: */
+  /* FIXME: FLAC should not need to know about this oddity */
+  if (ft->signal.encoding < SOX_ENCODING_SIZE_IS_WORD)
+    ft->signal.size = SOX_SIZE_16BIT;
+  ft->signal.encoding = SOX_ENCODING_FLAC;
+
+  encoder->bits_per_sample = (ft->signal.size > 4 ? 4 : ft->signal.size) << 3;
+
+  sox_report("encoding at %i bits per sample", encoder->bits_per_sample);
+
+  FLAC__stream_encoder_set_channels(encoder->flac, ft->signal.channels);
+  FLAC__stream_encoder_set_bits_per_sample(encoder->flac, encoder->bits_per_sample);
+  FLAC__stream_encoder_set_sample_rate(encoder->flac, ft->signal.rate);
+
+  { /* Check if rate is streamable: */
+    static const unsigned streamable_rates[] =
+      {8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
+    size_t i;
+    sox_bool streamable = sox_false;
+    for (i = 0; !streamable && i < array_length(streamable_rates); ++i)
+       streamable = (streamable_rates[i] == ft->signal.rate);
+    if (!streamable) {
+      sox_report("non-standard rate; output may not be streamable");
+      FLAC__stream_encoder_set_streamable_subset(encoder->flac, sox_false);
+    }
+  }
+
+#if FLAC_API_VERSION_CURRENT >= 10
+  FLAC__stream_encoder_set_compression_level(encoder->flac, compression_level);
+#else
+  {
     static struct {
       unsigned blocksize;
       FLAC__bool do_exhaustive_model_search;
@@ -327,7 +370,7 @@
       unsigned max_lpc_order;
       unsigned max_residual_partition_order;
       unsigned min_residual_partition_order;
-    } const options[] = {
+    } const options[MAX_COMPRESSION + 1] = {
       {1152, sox_false, sox_false, sox_false, 0, 2, 2},
       {1152, sox_false, sox_true, sox_true, 0, 2, 2},
       {1152, sox_false, sox_true, sox_false, 0, 3, 0},
@@ -338,21 +381,8 @@
       {4608, sox_true, sox_true, sox_false, 8, 6, 0},
       {4608, sox_true, sox_true, sox_false, 12, 6, 0},
     };
-    unsigned compression_level = array_length(options) - 1; /* Default to "best" */
-
-    if (ft->signal.compression != HUGE_VAL) {
-      compression_level = ft->signal.compression;
-      if (compression_level != ft->signal.compression || 
-          compression_level >= array_length(options)) {
-        sox_fail_errno(ft, SOX_EINVAL,
-                   "FLAC compression level must be a whole number from 0 to %i",
-                   array_length(options) - 1);
-        return SOX_EOF;
-      }
-    }
-
 #define SET_OPTION(x) do {\
-  sox_report("FLAC "#x" = %i", options[compression_level].x); \
+  sox_report(#x" = %i", options[compression_level].x); \
   FLAC__stream_encoder_set_##x(encoder->flac, options[compression_level].x);\
 } while (0)
     SET_OPTION(blocksize);
@@ -366,33 +396,8 @@
     }
 #undef SET_OPTION
   }
+#endif
 
-  /* FIXME: FLAC should not need to know about this oddity */
-  if (ft->signal.encoding < SOX_ENCODING_SIZE_IS_WORD)
-    ft->signal.size = SOX_SIZE_16BIT;
-  ft->signal.encoding = SOX_ENCODING_FLAC;
-
-  encoder->bits_per_sample = (ft->signal.size > 4 ? 4 : ft->signal.size) << 3;
-
-  sox_report("FLAC encoding at %i bits per sample", encoder->bits_per_sample);
-
-  FLAC__stream_encoder_set_channels(encoder->flac, ft->signal.channels);
-  FLAC__stream_encoder_set_bits_per_sample(encoder->flac, encoder->bits_per_sample);
-  FLAC__stream_encoder_set_sample_rate(encoder->flac, ft->signal.rate);
-
-  { /* Check if rate is streamable: */
-    static const unsigned streamable_rates[] =
-      {8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
-    size_t i;
-    sox_bool streamable = sox_false;
-    for (i = 0; !streamable && i < array_length(streamable_rates); ++i)
-       streamable = (streamable_rates[i] == ft->signal.rate);
-    if (!streamable) {
-      sox_report("FLAC: non-standard rate; output may not be streamable");
-      FLAC__stream_encoder_set_streamable_subset(encoder->flac, sox_false);
-    }
-  }
-
   if (ft->length != 0) {
     FLAC__stream_encoder_set_total_samples_estimate(encoder->flac, (FLAC__uint64)ft->length);
 
@@ -479,11 +484,22 @@
   unsigned i;
 
   for (i = 0; i < len; ++i) {
+    long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i], ft->clips);
+    encoder->decoded_samples[i] = pcm >> (32 - encoder->bits_per_sample);
     switch (encoder->bits_per_sample) {
-      case  8: encoder->decoded_samples[i] = SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips); break;
-      case 16: encoder->decoded_samples[i] = SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips); break;
-      case 24: encoder->decoded_samples[i] = SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips); break;
-      case 32: encoder->decoded_samples[i] = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips); break;
+      case  8: encoder->decoded_samples[i] =
+          SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips);
+        break;
+      case 16: encoder->decoded_samples[i] =
+          SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips);
+        break;
+      case 24: encoder->decoded_samples[i] = /* sign extension: */
+          SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips) << 8;
+        encoder->decoded_samples[i] >>= 8;
+        break;
+      case 32: encoder->decoded_samples[i] =
+          SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips);
+        break;
     }
   }
   FLAC__stream_encoder_process_interleaved(encoder->flac, encoder->decoded_samples, len / ft->signal.channels);
@@ -512,6 +528,10 @@
 
 
 
+/*
+ * N.B.  Do not call this function with offset=0 when file-pointer
+ * is already 0 or a block of decoded FLAC data will be discarded.
+ */
 static int seek(sox_format_t * ft, sox_size_t offset)
 {
   Decoder * decoder = (Decoder *) ft->priv;