From 5a3f10131eaeaa9336b8f8c501e0051a2ee69ec5 Mon Sep 17 00:00:00 2001 From: Brad Midgley Date: Thu, 25 Oct 2007 02:25:34 +0000 Subject: Frederic's conformance tests it needs build system integration, including -lsndfile to link this app should compile only if libsndfile-dev is present 'make install' should ignore it --- sbc/sbctester.c | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 sbc/sbctester.c (limited to 'sbc/sbctester.c') diff --git a/sbc/sbctester.c b/sbc/sbctester.c new file mode 100644 index 00000000..55ab28c0 --- /dev/null +++ b/sbc/sbctester.c @@ -0,0 +1,358 @@ +/* * + * Copyright (C) 2007 by Frederic Dalleau * + * fdalleau@free.fr * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/* + +A2DP Test Specification Chapter 4.6 (p 25) +namely SBC codec conformance test +This is a test procedure for SBC + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#define MAXCHANNELS 2 +#define MAXFRAMESTESTED infostst->frames +#define TSTSAMPLEFACTOR(x) (x) +#define DEFACCURACY 7 + +/* temporary */ +#ifndef VERSION +#define VERSION "1" +#endif + +void usage() +{ + printf("SBC codec conformance test (see Chapter 4.6, p. 25) ver %s\n", VERSION); + printf("Copyright (c) 2007 Frederic Dalleau\n\n"); + + //printf("This is a mandatory test case, but alternative methods exists.\n\n"); + + printf("Usage:\n" + "\tsbctester reference.wav checkfile.wav\n" + "\tsbctester integer\n" + "\n"); + + printf("\tTo test the encoder:\n"); + printf("\tUse a reference codec to encode original.wav to reference.sbc\n"); + printf("\tUse sbcenc to encode original.wav to checkfile.sbc\n"); + printf("\tDecode both file using the reference decoder\n"); + printf("\trun sbctester with these two wav files to get the result\n"); + + printf("\n\tA file called out.csv is generated to use the data in a spreadsheet application or database.\n\n"); +} + +double sampletobits(short sample16, int verbose) +{ + double bits = 0; + int i; + unsigned short bit; + + if (verbose) + printf("=======> sampletobits(%hd, %04hX)\n", sample16, sample16); + + // Bit 0 is MSB + if (sample16 < 0) + bits = -1; + + if (verbose) + printf("%d", (sample16 < 0) ? 1 : 0); + + // Bit 15 is LSB + for (i = 1; i < 16; i++) { + bit = (unsigned short) sample16; + bit >>= 15 - i; + bit %= 2; + + if (verbose) + printf("%d", bit); + + if (bit) + bits += (1.0 / pow(2.0, i)); + } + + if (verbose) + printf("\n"); + return bits; +} + +int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, SF_INFO * infostst, int accuracy, char *csvname) +{ + int i, j, err = 0, verdict = 0; + short refsample[MAXCHANNELS], tstsample[MAXCHANNELS]; + double refbits, tstbits; + double rms; + double rms_accu[MAXCHANNELS]; + double rms_level[MAXCHANNELS]; + double rms_limit = 1.0 / (pow(2.0, accuracy - 1) * pow(12.0, 0.5)); + FILE *csv = NULL; + int r1, r2; + + if (csvname) + csv = fopen(csvname, "wt"); + + if (csv) { + fprintf(csv, "num;"); + for (j = 0; j < infostst->channels; j++) + fprintf(csv, "ref channel %d;tst channel %d;", j, j); + fprintf(csv, "\r\n"); + } + + sf_seek(sndref, 0, SEEK_SET); + sf_seek(sndtst, 0, SEEK_SET); + memset(rms_accu, 0, sizeof(rms_accu)); + memset(rms_level, 0, sizeof(rms_level)); + + for (i = 0; i < MAXFRAMESTESTED; i++) { + if (csv) + fprintf(csv, "%d;", i); + + r1 = sf_read_short(sndref, refsample, infostst->channels); + if (r1 != infostst->channels) { + printf("Failed to read reference data:%s (r1=%d, channels=%d)", sf_strerror(sndref), r1, infostst->channels); + err = -1; + goto error; + } + + r2 = sf_read_short(sndtst, tstsample, infostst->channels); + if (r2 != infostst->channels) { + printf("Failed to read test data:%s (r2=%d, channels=%d)\n", sf_strerror(sndtst), r2, infostst->channels); + err = -1; + goto error; + } + + for (j = 0; j < infostst->channels; j++) { + if (csv) + fprintf(csv, "%d;%d;", refsample[j], tstsample[j]); + + refbits = sampletobits(refsample[j], 0); + tstbits = sampletobits(TSTSAMPLEFACTOR(tstsample[j]), 0); + + rms_accu[j] += pow(tstbits - refbits, 2.0); + } + + if (csv) + fprintf(csv, "\r\n"); + } + + printf("Limit: %f\n", rms_limit); + + for (j = 0; j < infostst->channels; j++) { + printf("Channel %d\n", j); + printf("Accumulated %f\n", rms_accu[j]); + rms_accu[j] /= (double) infostst->frames; + printf("Accumulated / %f = %f\n", (double) infostst->frames, rms_accu[j]); + rms_level[j] = sqrt(rms_accu[j]); + printf("Level = %f (%f x %f = %f)\n", rms_level[j], rms_level[j], rms_level[j], rms_level[j] * rms_level[j]); + } + + verdict = 1; + for (j = 0; j < infostst->channels; j++) { + printf("Channel %d: %f\n", j, rms_level[j]); + + if (rms_level[j] > rms_limit) + verdict = 0; + } + + printf("%s return %d\n", __FUNCTION__, verdict); + + + error: + + if (csv) + fclose(csv); + + return (err < 0) ? err : verdict; +} + +int check_sample() +{ + return 0; +} + +int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, SF_INFO * infostst, int accuracy) +{ + int i, j, err = 0, verdict = 0; + short refsample[MAXCHANNELS], tstsample[MAXCHANNELS], refmax[MAXCHANNELS], tstmax[MAXCHANNELS]; + double refbits, tstbits; + double rms_absolute = 1.0 / (pow(2, accuracy - 2)); + double calc_max[MAXCHANNELS]; + int calc_count = 0; + short r1, r2; + double cur_diff; + + memset(&refmax, 0, sizeof(refmax)); + memset(&tstmax, 0, sizeof(tstmax)); + memset(&calc_max, 0, sizeof(calc_max)); + memset(&refsample, 0, sizeof(refsample)); + memset(&tstsample, 0, sizeof(tstsample)); + + verdict = 1; + sf_seek(sndref, 0, SEEK_SET); + sf_seek(sndtst, 0, SEEK_SET); + + printf("Absolute max: %f\n", rms_absolute); + for (i = 0; i < MAXFRAMESTESTED; i++) { + r1 = sf_read_short(sndref, refsample, infostst->channels); + + if (r1 != infostst->channels) { + printf("Failed to read reference data:%s (r1=%d, channels=%d)", sf_strerror(sndref), r1, infostst->channels); + err = -1; + goto error; + } + + r2 = sf_read_short(sndtst, tstsample, infostst->channels); + if (r2 != infostst->channels) { + printf("Failed to read test data:%s (r2=%d, channels=%d)\n", sf_strerror(sndtst), r2, infostst->channels); + err = -1; + goto error; + } + + for (j = 0; j < infostst->channels; j++) { + refbits = sampletobits(refsample[j], 0); + tstbits = sampletobits(TSTSAMPLEFACTOR(tstsample[j]), 0); + + cur_diff = fabs(tstbits - refbits); + + if (cur_diff > rms_absolute) { + calc_count++; + //printf("Channel %d exceeded : fabs(%f - %f) = %f > %f\n", j, tstbits, refbits, cur_diff, rms_absolute); + verdict = 0; + } + if (cur_diff > calc_max[j]) { + calc_max[j] = cur_diff; + refmax[j] = refsample[j]; + tstmax[j] = tstsample[j]; + } + } + } + + for (j = 0; j < infostst->channels; j++) { + printf("Calculated max: %f (%hd-%hd=%hd)\n", calc_max[j], tstmax[j], refmax[j], tstmax[j] - refmax[j]); + } + + printf("%s return %d\n", __FUNCTION__, verdict); + + error: + + return (err < 0) ? err : verdict; +} + +int main(int argc, char *argv[]) +{ + int err = 0; + int rms_absolute, pass_rms, pass_absolute, pass, accuracy; + char *ref; + char *tst; + SNDFILE *sndref = NULL; + SNDFILE *sndtst = NULL; + SF_INFO infosref; + SF_INFO infostst; + + if (argc == 2) { + double db; + + printf("Test sampletobits\n"); + db = sampletobits((short) atoi(argv[1]), 1); + printf("db = %f\n", db); + exit(0); + } + + if (argc < 3) { + usage(); + exit(1); + } + + ref = argv[1]; + tst = argv[2]; + + // open both files + printf("opening reference %s\n", ref); + + sndref = sf_open(ref, SFM_READ, &infosref); + if (!sndref) { + printf("Failed to open reference file\n"); + err = -1; + goto error; + } + + printf("opening testfile %s\n", tst); + sndtst = sf_open(tst, SFM_READ, &infostst); + if (!sndtst) { + printf("Failed to open test file\n"); + err = -1; + goto error; + } + + printf("reference:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", (int) infosref.frames, (int) infosref.samplerate, (int) infosref.channels); + printf("testfile:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", (int) infostst.frames, (int) infostst.samplerate, (int) infostst.channels); + + // check number of channels + if (infosref.channels > 2 || infostst.channels > 2) { + printf("Too many channels\n"); + err = -1; + goto error; + } + // compare number of samples + if (infosref.samplerate != infostst.samplerate || infosref.channels != infostst.channels) { + printf("Cannot compare files with different charasteristics\n"); + err = -1; + goto error; + } + + accuracy = DEFACCURACY; + printf("Accuracy: %d\n", accuracy); + + // Condition 1 rms level + pass_rms = calculate_rms_level(sndref, &infosref, sndtst, &infostst, accuracy, "out.csv"); + + if (pass_rms < 0) { + err = pass_rms; + goto error; + } + // Condition 2 absolute difference + pass_absolute = check_absolute_diff(sndref, &infosref, sndtst, &infostst, accuracy); + + if (pass_absolute < 0) { + err = pass_absolute; + goto error; + } + // Verdict + pass = pass_rms && pass_absolute; + printf("Verdict: %s\n", pass ? "pass" : "fail"); + + error: + + if (sndref) + sf_close(sndref); + + if (sndtst) + sf_close(sndtst); + + return err; +} -- cgit From a6b3daeb44d9b6f0d47fbe0cbfc6612c061352cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Oct 2007 10:51:03 +0000 Subject: First round of cleanups --- sbc/sbctester.c | 112 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 57 deletions(-) (limited to 'sbc/sbctester.c') diff --git a/sbc/sbctester.c b/sbc/sbctester.c index 55ab28c0..0b35a335 100644 --- a/sbc/sbctester.c +++ b/sbc/sbctester.c @@ -1,30 +1,26 @@ -/* * - * Copyright (C) 2007 by Frederic Dalleau * - * fdalleau@free.fr * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - /* - -A2DP Test Specification Chapter 4.6 (p 25) -namely SBC codec conformance test -This is a test procedure for SBC - -*/ + * + * Bluetooth low-complexity, subband codec (SBC) library + * + * Copyright (C) 2007 Marcel Holtmann + * Copyright (C) 2007 Frederic Dalleau + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ #ifdef HAVE_CONFIG_H #include @@ -41,18 +37,11 @@ This is a test procedure for SBC #define TSTSAMPLEFACTOR(x) (x) #define DEFACCURACY 7 -/* temporary */ -#ifndef VERSION -#define VERSION "1" -#endif - -void usage() +static void usage() { - printf("SBC codec conformance test (see Chapter 4.6, p. 25) ver %s\n", VERSION); + printf("SBC conformance test ver %s\n", VERSION); printf("Copyright (c) 2007 Frederic Dalleau\n\n"); - //printf("This is a mandatory test case, but alternative methods exists.\n\n"); - printf("Usage:\n" "\tsbctester reference.wav checkfile.wav\n" "\tsbctester integer\n" @@ -67,7 +56,7 @@ void usage() printf("\n\tA file called out.csv is generated to use the data in a spreadsheet application or database.\n\n"); } -double sampletobits(short sample16, int verbose) +static double sampletobits(short sample16, int verbose) { double bits = 0; int i; @@ -98,10 +87,13 @@ double sampletobits(short sample16, int verbose) if (verbose) printf("\n"); + return bits; } -int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, SF_INFO * infostst, int accuracy, char *csvname) +static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, + SNDFILE * sndtst, SF_INFO * infostst, + int accuracy, char *csvname) { int i, j, err = 0, verdict = 0; short refsample[MAXCHANNELS], tstsample[MAXCHANNELS]; @@ -134,14 +126,16 @@ int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, r1 = sf_read_short(sndref, refsample, infostst->channels); if (r1 != infostst->channels) { - printf("Failed to read reference data:%s (r1=%d, channels=%d)", sf_strerror(sndref), r1, infostst->channels); + printf("Failed to read reference data: %s (r1=%d, channels=%d)", + sf_strerror(sndref), r1, infostst->channels); err = -1; goto error; } r2 = sf_read_short(sndtst, tstsample, infostst->channels); if (r2 != infostst->channels) { - printf("Failed to read test data:%s (r2=%d, channels=%d)\n", sf_strerror(sndtst), r2, infostst->channels); + printf("Failed to read test data: %s (r2=%d, channels=%d)\n", + sf_strerror(sndtst), r2, infostst->channels); err = -1; goto error; } @@ -168,7 +162,8 @@ int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, rms_accu[j] /= (double) infostst->frames; printf("Accumulated / %f = %f\n", (double) infostst->frames, rms_accu[j]); rms_level[j] = sqrt(rms_accu[j]); - printf("Level = %f (%f x %f = %f)\n", rms_level[j], rms_level[j], rms_level[j], rms_level[j] * rms_level[j]); + printf("Level = %f (%f x %f = %f)\n", + rms_level[j], rms_level[j], rms_level[j], rms_level[j] * rms_level[j]); } verdict = 1; @@ -181,24 +176,24 @@ int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, printf("%s return %d\n", __FUNCTION__, verdict); - - error: - +error: if (csv) fclose(csv); return (err < 0) ? err : verdict; } -int check_sample() +static int check_sample() { return 0; } -int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, SF_INFO * infostst, int accuracy) +static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, + SNDFILE * sndtst, SF_INFO * infostst, int accuracy) { int i, j, err = 0, verdict = 0; - short refsample[MAXCHANNELS], tstsample[MAXCHANNELS], refmax[MAXCHANNELS], tstmax[MAXCHANNELS]; + short refsample[MAXCHANNELS], tstsample[MAXCHANNELS], + short refmax[MAXCHANNELS], tstmax[MAXCHANNELS]; double refbits, tstbits; double rms_absolute = 1.0 / (pow(2, accuracy - 2)); double calc_max[MAXCHANNELS]; @@ -221,14 +216,16 @@ int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, r1 = sf_read_short(sndref, refsample, infostst->channels); if (r1 != infostst->channels) { - printf("Failed to read reference data:%s (r1=%d, channels=%d)", sf_strerror(sndref), r1, infostst->channels); + printf("Failed to read reference data: %s (r1=%d, channels=%d)", + sf_strerror(sndref), r1, infostst->channels); err = -1; goto error; } r2 = sf_read_short(sndtst, tstsample, infostst->channels); if (r2 != infostst->channels) { - printf("Failed to read test data:%s (r2=%d, channels=%d)\n", sf_strerror(sndtst), r2, infostst->channels); + printf("Failed to read test data: %s (r2=%d, channels=%d)\n", + sf_strerror(sndtst), r2, infostst->channels); err = -1; goto error; } @@ -253,13 +250,13 @@ int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, } for (j = 0; j < infostst->channels; j++) { - printf("Calculated max: %f (%hd-%hd=%hd)\n", calc_max[j], tstmax[j], refmax[j], tstmax[j] - refmax[j]); + printf("Calculated max: %f (%hd-%hd=%hd)\n", + calc_max[j], tstmax[j], refmax[j], tstmax[j] - refmax[j]); } printf("%s return %d\n", __FUNCTION__, verdict); - error: - +error: return (err < 0) ? err : verdict; } @@ -291,7 +288,6 @@ int main(int argc, char *argv[]) ref = argv[1]; tst = argv[2]; - // open both files printf("opening reference %s\n", ref); sndref = sf_open(ref, SFM_READ, &infosref); @@ -309,8 +305,10 @@ int main(int argc, char *argv[]) goto error; } - printf("reference:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", (int) infosref.frames, (int) infosref.samplerate, (int) infosref.channels); - printf("testfile:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", (int) infostst.frames, (int) infostst.samplerate, (int) infostst.channels); + printf("reference:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", + (int) infosref.frames, (int) infosref.samplerate, (int) infosref.channels); + printf("testfile:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", + (int) infostst.frames, (int) infostst.samplerate, (int) infostst.channels); // check number of channels if (infosref.channels > 2 || infostst.channels > 2) { @@ -319,7 +317,8 @@ int main(int argc, char *argv[]) goto error; } // compare number of samples - if (infosref.samplerate != infostst.samplerate || infosref.channels != infostst.channels) { + if (infosref.samplerate != infostst.samplerate || + infosref.channels != infostst.channels) { printf("Cannot compare files with different charasteristics\n"); err = -1; goto error; @@ -346,8 +345,7 @@ int main(int argc, char *argv[]) pass = pass_rms && pass_absolute; printf("Verdict: %s\n", pass ? "pass" : "fail"); - error: - +error: if (sndref) sf_close(sndref); -- cgit From 582a5f9cca7f8ae1f41076c8c3bc9c3bae851b09 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Oct 2007 11:06:39 +0000 Subject: Add build magic around sbctester program --- sbc/sbctester.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'sbc/sbctester.c') diff --git a/sbc/sbctester.c b/sbc/sbctester.c index 0b35a335..9d719e2e 100644 --- a/sbc/sbctester.c +++ b/sbc/sbctester.c @@ -98,7 +98,6 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, int i, j, err = 0, verdict = 0; short refsample[MAXCHANNELS], tstsample[MAXCHANNELS]; double refbits, tstbits; - double rms; double rms_accu[MAXCHANNELS]; double rms_level[MAXCHANNELS]; double rms_limit = 1.0 / (pow(2.0, accuracy - 1) * pow(12.0, 0.5)); @@ -183,16 +182,11 @@ error: return (err < 0) ? err : verdict; } -static int check_sample() -{ - return 0; -} - static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, SF_INFO * infostst, int accuracy) { int i, j, err = 0, verdict = 0; - short refsample[MAXCHANNELS], tstsample[MAXCHANNELS], + short refsample[MAXCHANNELS], tstsample[MAXCHANNELS]; short refmax[MAXCHANNELS], tstmax[MAXCHANNELS]; double refbits, tstbits; double rms_absolute = 1.0 / (pow(2, accuracy - 2)); @@ -263,7 +257,7 @@ error: int main(int argc, char *argv[]) { int err = 0; - int rms_absolute, pass_rms, pass_absolute, pass, accuracy; + int pass_rms, pass_absolute, pass, accuracy; char *ref; char *tst; SNDFILE *sndref = NULL; -- cgit From 15b172d3ff3e3968b0383ae50e32e9868067791c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Oct 2007 12:38:01 +0000 Subject: More cleanups --- sbc/sbctester.c | 94 ++++++++++++++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 52 deletions(-) (limited to 'sbc/sbctester.c') diff --git a/sbc/sbctester.c b/sbc/sbctester.c index 9d719e2e..f85d0bac 100644 --- a/sbc/sbctester.c +++ b/sbc/sbctester.c @@ -33,13 +33,12 @@ #include #define MAXCHANNELS 2 -#define MAXFRAMESTESTED infostst->frames -#define TSTSAMPLEFACTOR(x) (x) #define DEFACCURACY 7 static void usage() { printf("SBC conformance test ver %s\n", VERSION); + printf("Copyright (c) 2007 Marcel Holtmann\n\n"); printf("Copyright (c) 2007 Frederic Dalleau\n\n"); printf("Usage:\n" @@ -59,11 +58,11 @@ static void usage() static double sampletobits(short sample16, int verbose) { double bits = 0; - int i; unsigned short bit; + int i; if (verbose) - printf("=======> sampletobits(%hd, %04hX)\n", sample16, sample16); + printf("===> sampletobits(%hd, %04hX)\n", sample16, sample16); // Bit 0 is MSB if (sample16 < 0) @@ -95,14 +94,13 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, SF_INFO * infostst, int accuracy, char *csvname) { - int i, j, err = 0, verdict = 0; short refsample[MAXCHANNELS], tstsample[MAXCHANNELS]; double refbits, tstbits; double rms_accu[MAXCHANNELS]; double rms_level[MAXCHANNELS]; double rms_limit = 1.0 / (pow(2.0, accuracy - 1) * pow(12.0, 0.5)); FILE *csv = NULL; - int r1, r2; + int i, j, r1, r2, verdict; if (csvname) csv = fopen(csvname, "wt"); @@ -116,10 +114,11 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, sf_seek(sndref, 0, SEEK_SET); sf_seek(sndtst, 0, SEEK_SET); + memset(rms_accu, 0, sizeof(rms_accu)); memset(rms_level, 0, sizeof(rms_level)); - for (i = 0; i < MAXFRAMESTESTED; i++) { + for (i = 0; i < infostst->frames; i++) { if (csv) fprintf(csv, "%d;", i); @@ -127,16 +126,18 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, if (r1 != infostst->channels) { printf("Failed to read reference data: %s (r1=%d, channels=%d)", sf_strerror(sndref), r1, infostst->channels); - err = -1; - goto error; + if (csv) + fclose(csv); + return -1; } r2 = sf_read_short(sndtst, tstsample, infostst->channels); if (r2 != infostst->channels) { printf("Failed to read test data: %s (r2=%d, channels=%d)\n", sf_strerror(sndtst), r2, infostst->channels); - err = -1; - goto error; + if (csv) + fclose(csv); + return -1; } for (j = 0; j < infostst->channels; j++) { @@ -144,7 +145,7 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, fprintf(csv, "%d;%d;", refsample[j], tstsample[j]); refbits = sampletobits(refsample[j], 0); - tstbits = sampletobits(TSTSAMPLEFACTOR(tstsample[j]), 0); + tstbits = sampletobits(tstsample[j], 0); rms_accu[j] += pow(tstbits - refbits, 2.0); } @@ -162,10 +163,12 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, printf("Accumulated / %f = %f\n", (double) infostst->frames, rms_accu[j]); rms_level[j] = sqrt(rms_accu[j]); printf("Level = %f (%f x %f = %f)\n", - rms_level[j], rms_level[j], rms_level[j], rms_level[j] * rms_level[j]); + rms_level[j], rms_level[j], rms_level[j], + rms_level[j] * rms_level[j]); } verdict = 1; + for (j = 0; j < infostst->channels; j++) { printf("Channel %d: %f\n", j, rms_level[j]); @@ -175,17 +178,12 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, printf("%s return %d\n", __FUNCTION__, verdict); -error: - if (csv) - fclose(csv); - - return (err < 0) ? err : verdict; + return verdict; } static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, SNDFILE * sndtst, SF_INFO * infostst, int accuracy) { - int i, j, err = 0, verdict = 0; short refsample[MAXCHANNELS], tstsample[MAXCHANNELS]; short refmax[MAXCHANNELS], tstmax[MAXCHANNELS]; double refbits, tstbits; @@ -194,6 +192,7 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, int calc_count = 0; short r1, r2; double cur_diff; + int i, j, verdict; memset(&refmax, 0, sizeof(refmax)); memset(&tstmax, 0, sizeof(tstmax)); @@ -201,32 +200,31 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, memset(&refsample, 0, sizeof(refsample)); memset(&tstsample, 0, sizeof(tstsample)); - verdict = 1; sf_seek(sndref, 0, SEEK_SET); sf_seek(sndtst, 0, SEEK_SET); + verdict = 1; + printf("Absolute max: %f\n", rms_absolute); - for (i = 0; i < MAXFRAMESTESTED; i++) { + for (i = 0; i < infostst->frames; i++) { r1 = sf_read_short(sndref, refsample, infostst->channels); if (r1 != infostst->channels) { printf("Failed to read reference data: %s (r1=%d, channels=%d)", sf_strerror(sndref), r1, infostst->channels); - err = -1; - goto error; + return -1; } r2 = sf_read_short(sndtst, tstsample, infostst->channels); if (r2 != infostst->channels) { printf("Failed to read test data: %s (r2=%d, channels=%d)\n", sf_strerror(sndtst), r2, infostst->channels); - err = -1; - goto error; + return -1; } for (j = 0; j < infostst->channels; j++) { refbits = sampletobits(refsample[j], 0); - tstbits = sampletobits(TSTSAMPLEFACTOR(tstsample[j]), 0); + tstbits = sampletobits(tstsample[j], 0); cur_diff = fabs(tstbits - refbits); @@ -235,6 +233,7 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, //printf("Channel %d exceeded : fabs(%f - %f) = %f > %f\n", j, tstbits, refbits, cur_diff, rms_absolute); verdict = 0; } + if (cur_diff > calc_max[j]) { calc_max[j] = cur_diff; refmax[j] = refsample[j]; @@ -250,20 +249,18 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, printf("%s return %d\n", __FUNCTION__, verdict); -error: - return (err < 0) ? err : verdict; + return verdict; } int main(int argc, char *argv[]) { - int err = 0; - int pass_rms, pass_absolute, pass, accuracy; - char *ref; - char *tst; SNDFILE *sndref = NULL; SNDFILE *sndtst = NULL; SF_INFO infosref; SF_INFO infostst; + char *ref; + char *tst; + int pass_rms, pass_absolute, pass, accuracy; if (argc == 2) { double db; @@ -287,16 +284,15 @@ int main(int argc, char *argv[]) sndref = sf_open(ref, SFM_READ, &infosref); if (!sndref) { printf("Failed to open reference file\n"); - err = -1; - goto error; + exit(1); } printf("opening testfile %s\n", tst); sndtst = sf_open(tst, SFM_READ, &infostst); if (!sndtst) { printf("Failed to open test file\n"); - err = -1; - goto error; + sf_close(sndref); + exit(1); } printf("reference:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", @@ -307,14 +303,13 @@ int main(int argc, char *argv[]) // check number of channels if (infosref.channels > 2 || infostst.channels > 2) { printf("Too many channels\n"); - err = -1; goto error; } + // compare number of samples if (infosref.samplerate != infostst.samplerate || infosref.channels != infostst.channels) { printf("Cannot compare files with different charasteristics\n"); - err = -1; goto error; } @@ -323,28 +318,23 @@ int main(int argc, char *argv[]) // Condition 1 rms level pass_rms = calculate_rms_level(sndref, &infosref, sndtst, &infostst, accuracy, "out.csv"); - - if (pass_rms < 0) { - err = pass_rms; + if (pass_rms < 0) goto error; - } + // Condition 2 absolute difference pass_absolute = check_absolute_diff(sndref, &infosref, sndtst, &infostst, accuracy); - - if (pass_absolute < 0) { - err = pass_absolute; + if (pass_absolute < 0) goto error; - } + // Verdict pass = pass_rms && pass_absolute; printf("Verdict: %s\n", pass ? "pass" : "fail"); -error: - if (sndref) - sf_close(sndref); + return 0; - if (sndtst) - sf_close(sndtst); +error: + sf_close(sndref); + sf_close(sndtst); - return err; + exit(1); } -- cgit From 221a91a439f128912f6989d13ddf9926ad0a1572 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Oct 2007 12:41:13 +0000 Subject: Move the usage function around --- sbc/sbctester.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'sbc/sbctester.c') diff --git a/sbc/sbctester.c b/sbc/sbctester.c index f85d0bac..15e63c2a 100644 --- a/sbc/sbctester.c +++ b/sbc/sbctester.c @@ -35,26 +35,6 @@ #define MAXCHANNELS 2 #define DEFACCURACY 7 -static void usage() -{ - printf("SBC conformance test ver %s\n", VERSION); - printf("Copyright (c) 2007 Marcel Holtmann\n\n"); - printf("Copyright (c) 2007 Frederic Dalleau\n\n"); - - printf("Usage:\n" - "\tsbctester reference.wav checkfile.wav\n" - "\tsbctester integer\n" - "\n"); - - printf("\tTo test the encoder:\n"); - printf("\tUse a reference codec to encode original.wav to reference.sbc\n"); - printf("\tUse sbcenc to encode original.wav to checkfile.sbc\n"); - printf("\tDecode both file using the reference decoder\n"); - printf("\trun sbctester with these two wav files to get the result\n"); - - printf("\n\tA file called out.csv is generated to use the data in a spreadsheet application or database.\n\n"); -} - static double sampletobits(short sample16, int verbose) { double bits = 0; @@ -252,6 +232,27 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, return verdict; } +static void usage() +{ + printf("SBC conformance test ver %s\n", VERSION); + printf("Copyright (c) 2007 Marcel Holtmann\n"); + printf("Copyright (c) 2007 Frederic Dalleau\n\n"); + + printf("Usage:\n" + "\tsbctester reference.wav checkfile.wav\n" + "\tsbctester integer\n" + "\n"); + + printf("To test the encoder:\n"); + printf("\tUse a reference codec to encode original.wav to reference.sbc\n"); + printf("\tUse sbcenc to encode original.wav to checkfile.sbc\n"); + printf("\tDecode both file using the reference decoder\n"); + printf("\tRun sbctester with these two wav files to get the result\n\n"); + + printf("\tA file called out.csv is generated to use the data in a\n"); + printf("\tspreadsheet application or database.\n\n"); +} + int main(int argc, char *argv[]) { SNDFILE *sndref = NULL; -- cgit From 9138f99acb799d7ce702afb357c134042f933f4b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 1 Nov 2007 15:27:38 +0000 Subject: Coding style cleanup --- sbc/sbctester.c | 64 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 24 deletions(-) (limited to 'sbc/sbctester.c') diff --git a/sbc/sbctester.c b/sbc/sbctester.c index 15e63c2a..af4d1244 100644 --- a/sbc/sbctester.c +++ b/sbc/sbctester.c @@ -44,14 +44,14 @@ static double sampletobits(short sample16, int verbose) if (verbose) printf("===> sampletobits(%hd, %04hX)\n", sample16, sample16); - // Bit 0 is MSB + /* Bit 0 is MSB */ if (sample16 < 0) bits = -1; if (verbose) printf("%d", (sample16 < 0) ? 1 : 0); - // Bit 15 is LSB + /* Bit 15 is LSB */ for (i = 1; i < 16; i++) { bit = (unsigned short) sample16; bit >>= 15 - i; @@ -104,8 +104,10 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, r1 = sf_read_short(sndref, refsample, infostst->channels); if (r1 != infostst->channels) { - printf("Failed to read reference data: %s (r1=%d, channels=%d)", - sf_strerror(sndref), r1, infostst->channels); + printf("Failed to read reference data: %s " + "(r1=%d, channels=%d)", + sf_strerror(sndref), r1, + infostst->channels); if (csv) fclose(csv); return -1; @@ -113,8 +115,10 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, r2 = sf_read_short(sndtst, tstsample, infostst->channels); if (r2 != infostst->channels) { - printf("Failed to read test data: %s (r2=%d, channels=%d)\n", - sf_strerror(sndtst), r2, infostst->channels); + printf("Failed to read test data: %s " + "(r2=%d, channels=%d)\n", + sf_strerror(sndtst), r2, + infostst->channels); if (csv) fclose(csv); return -1; @@ -122,7 +126,8 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, for (j = 0; j < infostst->channels; j++) { if (csv) - fprintf(csv, "%d;%d;", refsample[j], tstsample[j]); + fprintf(csv, "%d;%d;", refsample[j], + tstsample[j]); refbits = sampletobits(refsample[j], 0); tstbits = sampletobits(tstsample[j], 0); @@ -140,7 +145,8 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, printf("Channel %d\n", j); printf("Accumulated %f\n", rms_accu[j]); rms_accu[j] /= (double) infostst->frames; - printf("Accumulated / %f = %f\n", (double) infostst->frames, rms_accu[j]); + printf("Accumulated / %f = %f\n", (double) infostst->frames, + rms_accu[j]); rms_level[j] = sqrt(rms_accu[j]); printf("Level = %f (%f x %f = %f)\n", rms_level[j], rms_level[j], rms_level[j], @@ -162,7 +168,8 @@ static int calculate_rms_level(SNDFILE * sndref, SF_INFO * infosref, } static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, - SNDFILE * sndtst, SF_INFO * infostst, int accuracy) + SNDFILE * sndtst, SF_INFO * infostst, + int accuracy) { short refsample[MAXCHANNELS], tstsample[MAXCHANNELS]; short refmax[MAXCHANNELS], tstmax[MAXCHANNELS]; @@ -190,15 +197,19 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, r1 = sf_read_short(sndref, refsample, infostst->channels); if (r1 != infostst->channels) { - printf("Failed to read reference data: %s (r1=%d, channels=%d)", - sf_strerror(sndref), r1, infostst->channels); + printf("Failed to read reference data: %s " + "(r1=%d, channels=%d)", + sf_strerror(sndref), r1, + infostst->channels); return -1; } r2 = sf_read_short(sndtst, tstsample, infostst->channels); if (r2 != infostst->channels) { - printf("Failed to read test data: %s (r2=%d, channels=%d)\n", - sf_strerror(sndtst), r2, infostst->channels); + printf("Failed to read test data: %s " + "(r2=%d, channels=%d)\n", + sf_strerror(sndtst), r2, + infostst->channels); return -1; } @@ -210,7 +221,7 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, if (cur_diff > rms_absolute) { calc_count++; - //printf("Channel %d exceeded : fabs(%f - %f) = %f > %f\n", j, tstbits, refbits, cur_diff, rms_absolute); + /* printf("Channel %d exceeded : fabs(%f - %f) = %f > %f\n", j, tstbits, refbits, cur_diff, rms_absolute); */ verdict = 0; } @@ -224,7 +235,8 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, for (j = 0; j < infostst->channels; j++) { printf("Calculated max: %f (%hd-%hd=%hd)\n", - calc_max[j], tstmax[j], refmax[j], tstmax[j] - refmax[j]); + calc_max[j], tstmax[j], refmax[j], + tstmax[j] - refmax[j]); } printf("%s return %d\n", __FUNCTION__, verdict); @@ -297,17 +309,19 @@ int main(int argc, char *argv[]) } printf("reference:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", - (int) infosref.frames, (int) infosref.samplerate, (int) infosref.channels); + (int) infosref.frames, (int) infosref.samplerate, + (int) infosref.channels); printf("testfile:\n\t%d frames,\n\t%d hz,\n\t%d channels\n", - (int) infostst.frames, (int) infostst.samplerate, (int) infostst.channels); + (int) infostst.frames, (int) infostst.samplerate, + (int) infostst.channels); - // check number of channels + /* check number of channels */ if (infosref.channels > 2 || infostst.channels > 2) { printf("Too many channels\n"); goto error; } - // compare number of samples + /* compare number of samples */ if (infosref.samplerate != infostst.samplerate || infosref.channels != infostst.channels) { printf("Cannot compare files with different charasteristics\n"); @@ -317,17 +331,19 @@ int main(int argc, char *argv[]) accuracy = DEFACCURACY; printf("Accuracy: %d\n", accuracy); - // Condition 1 rms level - pass_rms = calculate_rms_level(sndref, &infosref, sndtst, &infostst, accuracy, "out.csv"); + /* Condition 1 rms level */ + pass_rms = calculate_rms_level(sndref, &infosref, sndtst, &infostst, + accuracy, "out.csv"); if (pass_rms < 0) goto error; - // Condition 2 absolute difference - pass_absolute = check_absolute_diff(sndref, &infosref, sndtst, &infostst, accuracy); + /* Condition 2 absolute difference */ + pass_absolute = check_absolute_diff(sndref, &infosref, sndtst, + &infostst, accuracy); if (pass_absolute < 0) goto error; - // Verdict + /* Verdict */ pass = pass_rms && pass_absolute; printf("Verdict: %s\n", pass ? "pass" : "fail"); -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- sbc/sbctester.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sbc/sbctester.c') diff --git a/sbc/sbctester.c b/sbc/sbctester.c index af4d1244..260f34ae 100644 --- a/sbc/sbctester.c +++ b/sbc/sbctester.c @@ -2,8 +2,8 @@ * * Bluetooth low-complexity, subband codec (SBC) library * - * Copyright (C) 2007 Marcel Holtmann - * Copyright (C) 2007 Frederic Dalleau + * Copyright (C) 2007-2008 Marcel Holtmann + * Copyright (C) 2007-2008 Frederic Dalleau * * * This program is free software; you can redistribute it and/or modify @@ -247,8 +247,8 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref, static void usage() { printf("SBC conformance test ver %s\n", VERSION); - printf("Copyright (c) 2007 Marcel Holtmann\n"); - printf("Copyright (c) 2007 Frederic Dalleau\n\n"); + printf("Copyright (c) 2007-2008 Marcel Holtmann\n"); + printf("Copyright (c) 2007-2008 Frederic Dalleau\n\n"); printf("Usage:\n" "\tsbctester reference.wav checkfile.wav\n" -- cgit