ref: 37016e01527e98e3d2240d0d49454a4abc5631c5
parent: 7b4a6289ed0b1d27ea0660dbac1908d0ad6ec3df
author: Mark Harris <mark.hsj@gmail.com>
date: Fri Sep 14 16:43:34 EDT 2018
opusdec, opusenc: Fix float WAV on big endian host WAV uses little endian for floats so they must be byte-swapped.
--- a/src/audio-in.c
+++ b/src/audio-in.c
@@ -73,6 +73,7 @@
#include <ogg/ogg.h>
#include "encoder.h"
#include "opus_header.h"
+#include "wav_io.h"
#include "flac.h"
/* Macros for handling potentially large file offsets */
@@ -816,7 +817,7 @@
for (i=0; i < realsamples; i++)
for (j=0; j < f->channels; j++)
- buffer[i*f->channels+j] = buf[i*f->channels + f->channel_permute[j]];
+ buffer[i*f->channels+j] = get_le_float(buf + i*f->channels + f->channel_permute[j]);
return realsamples;
}
--- a/src/opusdec.c
+++ b/src/opusdec.c
@@ -511,7 +511,7 @@
frame_size -= in_len;
} else {
output=pcm;
- out_len=frame_size;
+ out_len=frame_size<maxout?(unsigned)frame_size:(unsigned)maxout;
frame_size=0;
}
@@ -534,25 +534,30 @@
out[i]=le_short(out[i]);
}
}
+ else if (le_short(1)!=(1)) {
+ /* ensure the floats are little endian */
+ for (i=0;i<(int)out_len*channels;i++)
+ put_le_float(buf+i, output[i]);
+ output = buf;
+ }
if (maxout>0)
{
#if defined WIN32 || defined _WIN32
if (!file) {
- ret=WIN_Play_Samples(out, sizeof(short) * channels * (out_len<maxout?out_len:maxout));
+ ret=WIN_Play_Samples(out, sizeof(short) * channels * out_len);
if (ret>0) ret/=sizeof(short)*channels;
else fprintf(stderr, "Error playing audio.\n");
} else
#elif defined HAVE_LIBSNDIO
if (!file) {
- ret=sio_write(hdl, out, sizeof(short) * channels * (out_len<maxout?out_len:maxout));
+ ret=sio_write(hdl, out, sizeof(short) * channels * out_len);
if (ret>0) ret/=sizeof(short)*channels;
else fprintf(stderr, "Error playing audio.\n");
} else
#endif
ret=fwrite(fp?(char *)output:(char *)out,
- (fp?sizeof(float):sizeof(short))*channels,
- out_len<maxout?out_len:maxout, fout);
+ (fp?sizeof(float):sizeof(short))*channels, out_len, fout);
sampout+=ret;
maxout-=ret;
}
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -70,7 +70,6 @@
#include <opus_multistream.h>
#include <opusenc.h>
-#include "wav_io.h"
#include "opus_header.h"
#include "encoder.h"
#include "diag_range.h"
--- a/src/wav_io.h
+++ b/src/wav_io.h
@@ -55,6 +55,36 @@
#endif
}
+static inline float get_le_float(float *ptr)
+{
+#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
+ float val;
+ char *lebytes = (char *)ptr;
+ char *nebytes = (char *)&val;
+ nebytes[0] = lebytes[3];
+ nebytes[1] = lebytes[2];
+ nebytes[2] = lebytes[1];
+ nebytes[3] = lebytes[0];
+ return val;
+#else
+ return *ptr;
+#endif
+}
+
+static inline void put_le_float(float *ptr, float val)
+{
+#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
+ char *lebytes = (char *)ptr;
+ char *nebytes = (char *)&val;
+ lebytes[0] = nebytes[3];
+ lebytes[1] = nebytes[2];
+ lebytes[2] = nebytes[1];
+ lebytes[3] = nebytes[0];
+#else
+ *ptr = val;
+#endif
+}
+
void adjust_wav_mapping(int mapping_family, int channels, unsigned char *stream_map);
int write_wav_header(FILE *file, int rate, int mapping_family, int channels, int fp);