28#define RAW_GUESS_DEBUG 0
31static FILE *g_raw_debug_file = NULL;
34static float AmpStat(
float *data,
size_t len)
36 float sum, sumofsquares, avg, variance, dev;
46 for (
size_t i = 0; i < len; i++) {
47 float x = fabs(data[i]);
49 sumofsquares += x * x;
53 variance = sumofsquares / len - (avg * avg);
69 for (
size_t i = 0; i + 1 < len; i++)
70 avg += fabs(data[i + 1] - data[i]);
71 avg = 1.0 - (avg / (len - 1) / 2.0);
82 for (
size_t i = 1; i < len; i++) {
85 v1 = data[i]-data[i-1];
97 for (
size_t i = 1; i + 1 < len; i += 2)
98 if (fabs(data[i + 1] - data[i]) > 2*fabs(data[i] - data[i - 1]) ||
99 2*fabs(data[i + 1] - data[i]) < fabs(data[i] - data[i - 1]))
102 return ((c * 2.0) / (len - 2));
109 char *rawData,
size_t dataSize,
110 float *data1,
float *data2,
size_t *len1,
size_t *len2)
113 size_t dataCount1 = 0;
114 size_t dataCount2 = 0;
122 dataSize -=
std::min(dataSize, offset);
138 while (rawCount + 7 < dataSize) {
140 for(
size_t i = 0; i < 8; i++)
141 u.c[7-i] = rawData[rawCount+i];
143 for(
size_t i = 0; i < 8; i++)
144 u.c[i] = rawData[rawCount+i];
145 data1[dataCount1] = (float)u.d;
157 while (rawCount + 3 < dataSize) {
159 for(
size_t i = 0; i < 4; i++)
160 u.c[3-i] = rawData[rawCount+i];
162 for(
size_t i = 0; i < 4; i++)
163 u.c[i] = rawData[rawCount+i];
164 data1[dataCount1] = u.f;
172 for(
size_t i = 0; i < dataCount1; i++) {
173 data2[i] = data1[2*i+1];
174 data1[i] = data1[2*i];
176 dataCount2 = dataCount1;
188 char *rawData,
int dataSizeIn,
189 float *data1,
float *data2,
size_t *len1,
size_t *len2)
192 size_t dataCount1 = 0;
193 size_t dataCount2 = 0;
198 if (offset && bits16) {
200 if (stereo && !bigendian) {
213 XO(
"Bad data size. Could not import audio"),
215 "Error:_Importing_raw_audio"
218 size_t dataSize = (size_t)dataSizeIn;
221 if (sign && bigendian)
222 while (rawCount + 1 < dataSize) {
225 (wxINT16_SWAP_ON_LE(*((
signed short *)
226 &rawData[rawCount])))
231 if (!sign && bigendian)
232 while (rawCount + 1 < dataSize) {
235 (wxUINT16_SWAP_ON_LE(*((
unsigned short *)
236 &rawData[rawCount])))
241 if (sign && !bigendian)
242 while (rawCount + 1 < dataSize) {
245 (wxINT16_SWAP_ON_BE(*((
signed short *)
246 &rawData[rawCount])))
251 if (!sign && !bigendian)
252 while (rawCount + 1 < dataSize) {
255 (wxUINT16_SWAP_ON_BE(*((
unsigned short *)
256 &rawData[rawCount])))
265 while (rawCount < dataSize) {
267 data1[dataCount1++] =
268 (*(
signed char *) (&rawData[rawCount++])) / 128.0;
272 while (rawCount < dataSize) {
274 data1[dataCount1++] =
275 (*(
unsigned char *) &rawData[rawCount++]) / 128.0 - 1.0;
282 for(
size_t i = 0; i < dataCount1; i++) {
283 data2[i] = data1[2*i+1];
284 data1[i] = data1[2*i];
286 dataCount2 = dataCount1;
294 size_t *out_offset,
unsigned *out_channels)
297 size_t bestOffset = 0;
300 float bestSmoothAvg = 1000.0;
303 bool guessStereo =
false;
304 unsigned stereoVotes = 0;
305 unsigned monoVotes = 0;
308 FILE *af = g_raw_debug_file;
309 wxFprintf(af,
"Testing float\n");
333 for(
unsigned int prec = 0; prec < 2; prec++) {
334 for(
int endian = 0; endian < 2; endian++) {
335 for(
size_t offset = 0; offset < (4 * prec + 4); offset++) {
336 unsigned finiteVotes = 0;
337 unsigned maxminVotes = 0;
341 wxFprintf(af,
"prec=%d endian=%d offset=%d\n",
342 prec, endian, (
int)offset);
345 for(
unsigned test = 0; test < numTests; test++) {
351 rawData[test].get(), dataSize,
352 data1.get(), data2.get(), &len1, &len2);
358 if (!(data1[i]>=0 || data1[i]<=0) ||
359 !(data2[i]>=0 || data2[i]<=0))
367 for(i = 1; i < len1; i++) {
373 for(i = 1; i < len2; i++) {
380 if (min < -0.01 && min >= -100000 &&
381 max > 0.01 && max <= 100000)
387 smoothAvg /= numTests;
390 wxFprintf(af,
"finite: %ud/%ud maxmin: %ud/%ud smooth: %f\n",
391 finiteVotes, numTests, maxminVotes, numTests,
395 if (finiteVotes > numTests/2 &&
396 finiteVotes > numTests-2 &&
397 maxminVotes > numTests/2 &&
398 smoothAvg < bestSmoothAvg) {
400 bestSmoothAvg = smoothAvg;
415 if (bestSmoothAvg >= 1000.0)
424 for (
unsigned test = 0; test < numTests; test++) {
425 float leftChannel, rightChannel, combinedChannel;
430 rawData[test].get(), dataSize,
431 data1.get(), data2.get(), &len1, &len2);
432 leftChannel =
JumpStat(data1.get(), len1);
433 rightChannel =
JumpStat(data2.get(), len2);
437 rawData[test].get(), dataSize,
438 data1.get(), data2.get(), &len1, &len2);
439 combinedChannel =
JumpStat(data1.get(), len1);
441 if (leftChannel > combinedChannel
442 && rightChannel > combinedChannel)
449 wxFprintf(af,
"stereo: %ud mono: %ud\n", stereoVotes, monoVotes);
452 guessStereo = (stereoVotes > monoVotes);
458 unsigned rstereoVotes = 0;
459 unsigned rmonoVotes = 0;
461 for (
unsigned test = 0; test < numTests; test++) {
467 rawData[test].get(), dataSize,
468 data1.get(), data2.get(), &len1, &len2);
472 wxFprintf(af,
"redundant: %f\n", redundant);
482 wxFprintf(af,
"rstereo: %ud rmono: %ud\n", rstereoVotes, rmonoVotes);
485 guessStereo = (rstereoVotes > rmonoVotes);
491 wxFprintf(af,
"stereo\n");
493 wxFprintf(af,
"mono\n");
496 *out_offset = bestOffset;
504 format = SF_FORMAT_RAW | SF_FORMAT_DOUBLE;
506 format = SF_FORMAT_RAW | SF_FORMAT_FLOAT;
511 format |= SF_ENDIAN_LITTLE;
518 bool guessSigned =
false;
519 bool guessStereo =
false;
520 unsigned signvotes = 0;
521 unsigned unsignvotes = 0;
522 unsigned stereoVotes = 0;
523 unsigned monoVotes = 0;
531 FILE *af = g_raw_debug_file;
532 wxFprintf(af,
"8-bit\n");
546 for (
unsigned test = 0; test < numTests; test++) {
547 float signL, signR, unsignL, unsignR;
550 false, rawData[test].get(), dataSize,
551 data1.get(), data2.get(), &len1, &len2);
552 signL =
JumpStat(data1.get(), len1);
553 signR =
JumpStat(data2.get(), len2);
555 false, rawData[test].get(), dataSize,
556 data1.get(), data2.get(), &len1, &len2);
557 unsignL =
JumpStat(data1.get(), len1);
558 unsignR =
JumpStat(data2.get(), len2);
572 wxFprintf(af,
"sign: %ud unsign: %ud\n", signvotes, unsignvotes);
575 guessSigned = (signvotes > unsignvotes);
579 wxFprintf(af,
"signed\n");
581 wxFprintf(af,
"unsigned\n");
590 for (
unsigned test = 0; test < numTests; test++) {
591 float leftChannel, rightChannel, combinedChannel;
593 Extract(0, guessSigned, 1, 0, 0, rawData[test].get(), dataSize, data1.get(),
594 data2.get(), &len1, &len2);
595 leftChannel =
JumpStat(data1.get(), len1);
596 rightChannel =
JumpStat(data2.get(), len2);
597 Extract(0, guessSigned, 0, 0, 0, rawData[test].get(), dataSize, data1.get(),
598 data2.get(), &len1, &len2);
599 combinedChannel =
JumpStat(data1.get(), len1);
601 if (leftChannel > combinedChannel
602 && rightChannel > combinedChannel)
609 wxFprintf(af,
"stereo: %ud mono: %ud\n", stereoVotes, monoVotes);
612 guessStereo = (stereoVotes > monoVotes);
618 unsigned rstereoVotes = 0;
619 unsigned rmonoVotes = 0;
621 for (
unsigned test = 0; test < numTests; test++) {
624 Extract(0, guessSigned, 0, 0, 0, rawData[test].get(), dataSize,
625 data1.get(), data2.get(), &len1, &len2);
629 wxFprintf(af,
"redundant: %f\n", redundant);
639 wxFprintf(af,
"rstereo: %ud rmono: %ud\n", rstereoVotes, rmonoVotes);
642 guessStereo = (rstereoVotes > rmonoVotes);
648 wxFprintf(af,
"stereo\n");
650 wxFprintf(af,
"mono\n");
659 return SF_FORMAT_RAW | SF_FORMAT_PCM_S8;
661 return SF_FORMAT_RAW | SF_FORMAT_PCM_U8;
665 size_t dataSize,
bool evenMSB,
666 size_t *out_offset,
unsigned *out_channels)
669 bool guessSigned =
false;
670 bool guessStereo =
false;
671 bool guessBigEndian =
false;
672 bool guessOffset =
false;
673 unsigned signvotes = 0;
674 unsigned unsignvotes = 0;
675 unsigned stereoVotes = 0;
676 unsigned monoVotes = 0;
677 unsigned formerVotes = 0;
678 unsigned latterVotes = 0;
686 FILE *af = g_raw_debug_file;
687 wxFprintf(af,
"16-bit\n");
694 for (
unsigned test = 0; test < numTests; test++) {
696 float signL, signR, unsignL, unsignR;
700 for (
size_t i = 0; i < dataSize / 2; i++)
701 rawData2[i] = rawData[test][2 * i + (evenMSB ? 0 : 1)];
706 0, rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
707 signL =
JumpStat(data1.get(), len1);
708 signR =
JumpStat(data2.get(), len2);
710 0, rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
711 unsignL =
JumpStat(data1.get(), len1);
712 unsignR =
JumpStat(data2.get(), len2);
726 wxFprintf(af,
"sign: %ud unsign: %ud\n", signvotes, unsignvotes);
729 guessSigned = (signvotes > unsignvotes);
733 wxFprintf(af,
"signed\n");
735 wxFprintf(af,
"unsigned\n");
742 for (
unsigned test = 0; test < numTests; test++) {
743 float leftChannel, rightChannel, combinedChannel;
747 for (
size_t i = 0; i < dataSize / 2; i++)
748 rawData2[i] = rawData[test][2 * i + (evenMSB ? 0 : 1)];
750 Extract(0, guessSigned, 1, 0, 0,
751 rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
752 leftChannel =
JumpStat(data1.get(), len1);
753 rightChannel =
JumpStat(data2.get(), len2);
754 Extract(0, guessSigned, 0, 0, 0,
755 rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
756 combinedChannel =
JumpStat(data1.get(), len1);
758 if (leftChannel > combinedChannel
759 && rightChannel > combinedChannel)
766 wxFprintf(af,
"stereoVotes: %ud monoVotes: %ud\n", stereoVotes, monoVotes);
769 guessStereo = (stereoVotes > monoVotes);
775 unsigned rstereoVotes = 0;
776 unsigned rmonoVotes = 0;
778 for (
unsigned test = 0; test < numTests; test++) {
784 for (
size_t i = 0; i < dataSize / 2; i++)
785 rawData2[i] = rawData[test][2 * i + (evenMSB ? 0 : 1)];
787 Extract(0, guessSigned, 0, 0, 0, rawData2.get(), dataSize / 2,
788 data1.get(), data2.get(), &len1, &len2);
799 wxFprintf(af,
"rstereoVotes: %ud rmonoVotes: %ud\n",
800 rstereoVotes, rmonoVotes);
803 guessStereo = (rstereoVotes > rmonoVotes);
809 wxFprintf(af,
"stereo\n");
811 wxFprintf(af,
"mono\n");
821 guessBigEndian = evenMSB;
825 wxFprintf(af,
"evenMSB: %d BE: %d\n", evenMSB, guessBigEndian);
828 for (
unsigned test = 0; test < numTests; test++) {
830 float former, latter;
836 for (
size_t i = 0; i + 1 < (dataSize / 4); i++)
838 rawData[test][4 * i + (evenMSB ? 0 : 1)];
840 for (
size_t i = 0; i + 1 < (dataSize / 2); i++)
842 rawData[test][2 * i + (evenMSB ? 0 : 1)];
845 Extract(1, guessSigned, guessStereo, guessBigEndian, guessOffset,
846 rawData[test].get(), dataSize-4, data1.get(), data2.get(), &len1, &len2);
848 offs=(!guessBigEndian);
850 for(
size_t i = 3; i + 4 < len1; i++) {
851 if (rawData2[offs+i-2]==rawData2[offs+i-1] &&
852 rawData2[offs+i]==rawData2[offs+i-1]+1 &&
853 rawData2[offs+i]==rawData2[offs+i+1]) {
854 former += data1[i]-data1[i-1];
859 Extract(1, guessSigned, guessStereo, !guessBigEndian,
860 !guessOffset, rawData[test].get(), dataSize, data1.get(), data2.get(),
863 offs=(guessBigEndian);
865 for(
size_t i = 3; i + 4 < len1; i++) {
866 if (rawData2[offs+i-2]==rawData2[offs+i-1] &&
867 rawData2[offs+i]==rawData2[offs+i-1]+1 &&
868 rawData2[offs+i]==rawData2[offs+i+1]) {
870 latter += data1[i]-data1[i-1];
875 wxFprintf(af,
"former: %f latter: %f\n", former, latter);
878 if (former <= latter)
885 wxFprintf(af,
"former (BE/LE): %ud latter (LE+/BE+): %ud\n",
886 formerVotes, latterVotes);
890 if (latterVotes > formerVotes*2) {
891 guessBigEndian = !guessBigEndian;
892 guessOffset = !guessOffset;
897 wxFprintf(af,
"big endian\n");
899 wxFprintf(af,
"little endian\n");
904 wxFprintf(af,
"offset 1 byte\n");
906 wxFprintf(af,
"no byte offset\n");
909 format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
914 format |= SF_ENDIAN_LITTLE;
928 size_t *out_offset,
unsigned *out_channels)
930 int format = SF_FORMAT_RAW;
931 bool guess16bit =
false;
939 unsigned evenMSBVotes = 0;
940 unsigned oddMSBVotes = 0;
943 FILE *af = g_raw_debug_file;
961 for (
unsigned test = 0; test < numTests; test++) {
965 false, rawData[test].get(), dataSize,
966 data1.get(), data2.get(), &len1, &len2);
967 even =
AmpStat(data1.get(), len1);
968 odd =
AmpStat(data2.get(), len2);
969 if ((even > 0.15) && (odd > 0.15)) {
971 wxFprintf(af,
"Both appear random: %.2f, %.2f.\n", even, odd);
974 else if ((even > 0.15) || (odd > 0.15))
986 evenMSB = (evenMSBVotes > oddMSBVotes);
989 wxFprintf(af,
"evenMSBVote: %ud oddMSBVote: %ud\n",
990 evenMSBVotes, oddMSBVotes);
991 wxFprintf(af,
"vote8: %ud vote16: %ud\n", vote8, vote16);
994 guess16bit = (vote8 <= vote16);
1001 out_offset, out_channels);
1007 size_t *out_offset,
unsigned *out_channels)
1009 const unsigned numTests = 11;
1010 size_t headerSkipSize = 64;
1011 size_t dataSize = 16384;
1012 int format = SF_FORMAT_RAW;
1018 FILE *af = fopen(
"raw.txt",
"a");
1019 g_raw_debug_file = af;
1020 wxFprintf(af,
"File: %s\n", in_fname);
1026 wxFFile in_wxFFile(in_fname,
wxT(
"rb"));
1029 if (!in_wxFFile.IsOpened())
1031 inf = in_wxFFile.fp();
1036 g_raw_debug_file = NULL;
1043 fseek(inf, 0, SEEK_END);
1044 fileLen = ftell(inf);
1049 if (fileLen < headerSkipSize)
1052 if (fileLen < dataSize)
1053 dataSize = fileLen / 2;
1055 wxASSERT( dataSize >= 4 );
1056 wxASSERT( dataSize <= fileLen );
1060 for (
unsigned test = 0; test < numTests; test++) {
1063 startPoint = (fileLen - dataSize) * (test + 1) / (numTests + 2);
1066 startPoint = (startPoint/16)*16;
1069 fseek(inf, headerSkipSize + startPoint, SEEK_SET);
1070 read_data = fread(rawData[test].get(), 1, dataSize, inf);
1071 if (read_data != dataSize && ferror(inf)) {
1072 perror(
"fread error in RawAudioGuess");
1088 out_offset, out_channels);
1094 out_offset, out_channels);
1099 g_raw_debug_file = NULL;
Declare abstract class AudacityException, some often-used subclasses, and GuardedCall.
@ BadUserAction
Indicates that the user performed an action that is not allowed.
static float AmpStat(float *data, size_t len)
static int Guess8Bit(unsigned numTests, const ArrayOf< char > rawData[], size_t dataSize, unsigned *out_channels)
int RawAudioGuess(const wxString &in_fname, size_t *out_offset, unsigned *out_channels)
static int GuessIntFormats(unsigned numTests, const ArrayOf< char > rawData[], size_t dataSize, size_t *out_offset, unsigned *out_channels)
static void Extract(bool bits16, bool sign, bool stereo, bool bigendian, bool offset, char *rawData, int dataSizeIn, float *data1, float *data2, size_t *len1, size_t *len2)
static float SecondDStat(float *data, size_t len)
static int Guess16Bit(unsigned numTests, const ArrayOf< char > rawData[], size_t dataSize, bool evenMSB, size_t *out_offset, unsigned *out_channels)
static float JumpStat(float *data, size_t len)
static void ExtractFloats(bool doublePrec, bool bigendian, bool stereo, size_t offset, char *rawData, size_t dataSize, float *data1, float *data2, size_t *len1, size_t *len2)
static float RedundantStereo(float *data, size_t len)
static int GuessFloatFormats(unsigned numTests, const ArrayOf< char > rawData[], size_t dataSize, size_t *out_offset, unsigned *out_channels)
A MessageBoxException that shows a given, unvarying string.
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
__finl float_x4 __vecc sqrt(const float_x4 &a)