shithub: opus-tools

Download patch

ref: 4ec47c8bfc87cd09ab79998f7e35bd87afd2041f
parent: 145fb7c90b7ba789aa4946945618d5165dbcf701
author: Mark Harris <mark.hsj@gmail.com>
date: Sun Sep 27 19:08:00 EDT 2020

opusenc: Allow big endian float and 24-bit input

--- a/src/audio-in.c
+++ b/src/audio-in.c
@@ -790,9 +790,17 @@
             }
         }
         else {
-            fprintf(stderr, _("Big endian 24 bit PCM data is not currently "
-                              "supported, aborting.\n"));
-            return 0;
+            for (i = 0; i < realsamples; i++)
+            {
+                for (j=0; j < f->channels; j++)
+                {
+                    buffer[i*f->channels+j] = ((buf[i*3*f->channels + 3*ch_permute[j]] << 16) |
+                      (((unsigned char *)buf)[i*3*f->channels + 3*ch_permute[j] + 1] << 8) |
+                      (((unsigned char *)buf)[i*3*f->channels + 3*ch_permute[j] + 2] & 0xff))
+                        / 8388608.0f;
+
+                }
+            }
         }
     }
     else {
@@ -815,9 +823,18 @@
     realsamples = (int)fread(buf, 4*f->channels, realsamples, f->f);
     f->samplesread += realsamples;
 
-    for (i=0; i < realsamples; i++)
-        for (j=0; j < f->channels; j++)
-            buffer[i*f->channels+j] = get_le_float(buf + i*f->channels + f->channel_permute[j]);
+    if (!f->bigendian) {
+        for (i=0; i < realsamples; i++)
+            for (j=0; j < f->channels; j++)
+                buffer[i*f->channels+j] =
+                    get_le_float(buf + i*f->channels + f->channel_permute[j]);
+    }
+    else {
+        for (i=0; i < realsamples; i++)
+            for (j=0; j < f->channels; j++)
+                buffer[i*f->channels+j] =
+                    get_be_float(buf + i*f->channels + f->channel_permute[j]);
+    }
 
     return realsamples;
 }
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -805,10 +805,6 @@
     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();
     exit(1);
--- a/src/wav_io.h
+++ b/src/wav_io.h
@@ -71,6 +71,22 @@
 #endif
 }
 
+static inline float get_be_float(float *ptr)
+{
+#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
+    return *ptr;
+#else
+    float val;
+    char *bebytes = (char *)ptr;
+    char *nebytes = (char *)&val;
+    nebytes[0] = bebytes[3];
+    nebytes[1] = bebytes[2];
+    nebytes[2] = bebytes[1];
+    nebytes[3] = bebytes[0];
+    return val;
+#endif
+}
+
 static inline void put_le_float(float *ptr, float val)
 {
 #if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )