shithub: opus-tools

Download patch

ref: 145fb7c90b7ba789aa4946945618d5165dbcf701
parent: 6b8af569b443ce3c4653aea62dd0339914b6088f
author: eblanca <eblanca@libero.it>
date: Sat Jun 20 17:00:53 EDT 2020

opusenc: support for single precision floating point raw samples

Closes https://github.com/xiph/opus-tools/pull/56
Signed-off-by: Mark Harris <mark.hsj@gmail.com>

--- a/man/opusenc.1
+++ b/man/opusenc.1
@@ -14,7 +14,7 @@
 .SH DESCRIPTION
 .B opusenc
 reads audio data in Wave, AIFF, FLAC, Ogg/FLAC,
-or raw PCM format and encodes it into an Ogg Opus stream.
+or raw PCM/float format and encodes it into an Ogg Opus stream.
 If the input file is "\fB\-\fR" audio data is read from stdin.
 Likewise, if the output file is "\fB\-\fR" the Ogg Opus stream
 is written to stdout.
@@ -289,6 +289,9 @@
 .TP
 .B --raw
 Interpret input as raw PCM data without headers.
+.TP
+.B --raw-float
+Interpret input as raw floating point data without headers.
 .TP
 .BI --raw-bits " N"
 Set bits/sample for raw input (default: 16).
--- a/src/audio-in.c
+++ b/src/audio-in.c
@@ -848,7 +848,10 @@
     for (i=0; i < wav->channels; i++)
       wav->channel_permute[i] = i;
 
-    opt->read_samples = wav_read;
+    if (opt->rawmode_f)
+        opt->read_samples = wav_ieee_read;
+    else
+        opt->read_samples = wav_read;
     opt->readdata = (void *)wav;
     opt->total_samples_per_channel = 0; /* raw mode, don't bother */
     return 1;
--- a/src/encoder.h
+++ b/src/encoder.h
@@ -24,6 +24,7 @@
     void *readdata;
     opus_int64 total_samples_per_channel;
     int rawmode;
+    int rawmode_f;
     int channels;
     long rate;
     int gain;
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -170,6 +170,7 @@
   printf(" --discard-pictures Don't keep pictures when transcoding\n");
   printf("\nInput options:\n");
   printf(" --raw              Interpret input as raw PCM data without headers\n");
+  printf(" --raw-float        Interpret input as raw float data without headers\n");
   printf(" --raw-bits n       Set bits/sample for raw input (default: 16)\n");
   printf(" --raw-rate n       Set sampling rate for raw input (default: 48000)\n");
   printf(" --raw-chan n       Set number of channels for raw input (default: 2)\n");
@@ -379,6 +380,7 @@
     {"raw-rate", required_argument, NULL, 0},
     {"raw-chan", required_argument, NULL, 0},
     {"raw-endianness", required_argument, NULL, 0},
+    {"raw-float", no_argument, NULL, 0},
     {"ignorelength", no_argument, NULL, 0},
     {"version", no_argument, NULL, 0},
     {"version-short", no_argument, NULL, 0},
@@ -464,6 +466,7 @@
   inopt.samplesize=16;
   inopt.endianness=0;
   inopt.rawmode=0;
+  inopt.rawmode_f=0;
   inopt.ignorelength=0;
   inopt.copy_comments=1;
   inopt.copy_pictures=1;
@@ -549,9 +552,9 @@
           inopt.rawmode=1;
           inopt.samplesize=atoi(optarg);
           save_cmd=0;
-          if (inopt.samplesize!=8&&inopt.samplesize!=16&&inopt.samplesize!=24) {
+          if (inopt.samplesize!=8&&inopt.samplesize!=16&&inopt.samplesize!=24&&inopt.samplesize!=32) {
             fatal("Invalid bit-depth: %s\n"
-              "--raw-bits must be one of 8, 16, or 24\n", optarg);
+              "--raw-bits must be one of 8, 16, 24, or 32\n", optarg);
           }
         } else if (strcmp(optname, "raw-rate")==0) {
           inopt.rawmode=1;
@@ -565,6 +568,10 @@
           inopt.rawmode=1;
           inopt.endianness=atoi(optarg);
           save_cmd=0;
+        } else if (strcmp(optname, "raw-float")==0) {
+          inopt.rawmode=1;
+          inopt.rawmode_f=1;
+          inopt.samplesize=32;
         } else if (strcmp(optname, "downmix-mono")==0) {
           downmix=1;
         } else if (strcmp(optname, "downmix-stereo")==0) {
@@ -789,6 +796,18 @@
         exit(1);
         break;
     }
+  }
+  if (inopt.samplesize==32&&(!inopt.rawmode_f)) {
+    fatal("Invalid bit-depth:\n"
+      "--raw-bits can only be 32 for float sample format\n");
+  }
+  if (inopt.samplesize<24&&(inopt.rawmode_f)) {
+    fatal("Invalid bit-depth:\n"
+      "--raw-bits must be 24 or 32 for float sample format\n");
+  }
+  if (inopt.endianness==1&&(inopt.rawmode_f)) {
+    fprintf(stderr,"Notice: Setting big-endian with floating point samples does not make sense, fixing.\n");
+    inopt.endianness=0;
   }
   if (argc_utf8-optind!=2) {
     usage();