Nic Roets
2005-Sep-26 08:33 UTC
[Speex-dev] Precomputing the remaining floating point operations.
I see there are still some floating point operations left in the codec init(ialization) code. Changing that code to fixed point is not only difficult (due to the trigonometric functions etc) but may also degrade the precision. Here is an idea whereby we can easily precompute (record) all those values on a powerful processor and then use (replay) them on an embedded processor / DSP. The only requirement is that 'xxx_init_xxx' should be called in exactly the same environment in both cases (e.g. FIXED_POINT and with the same mode or sequence of modes). All that's needed is to include the code segment below in one of the .h files and wrap all those float calculations in RECOPLAY, e.g. int sqrt2 = RECOPLAY(sqrt(2)*16384) I've also made RECOPLAY_MARK(name) to synchronize the process. #ifdef RECORD #include <stdio.h> extern FILE *recordFile; #define _RECOPLAY_FOPEN \ if (!recordFile && (recordFile = fopen ("precompute.c", "w")) != NULL) { \ fprintf (recordFile, "#include \"config.h\"\n\ #ifndef EMBEDDED\n\ #include <stdio.h>\n\ FILE *recordFile = NULL;\n\ #else\n\ int recordDefault[]={\n");\ atexit (CloseRecordFile); \ } \ #define RECOPLAY_MARK(name) { _RECOPLAY_FOPEN; \ if (recordFile) fprintf (recordFile, "}, record"#name"[] = {\n"); \ } #define RECOPLAY(x) ({ \ int v = (x); \ _RECOPLAY_FOPEN; \ fprintf (recordFile, " %d,\n", v); \ v; \ }) static void CloseRecordFile (void) { if (recordFile) { fprintf (recordFile, "}, *recordPtr = recordDefault;\n #endif\n"); fclose (recordFile); } } #else /* Not recording */ #ifndef EMBEDDED #define RECOPLAY_MARK(x) #define RECOPLAY(x) (x) #else extern int *recordPtr; #define RECOPLAY_MARK(x) {extern int record ## x[]; recordPtr = record ## x; } #define RECOPLAY(x) *recordPtr++ /* Embedded version of RECOPLAY does not evaluate 'x' */ #endif #endif
Jean-Marc Valin
2005-Sep-26 23:10 UTC
[Speex-dev] Precomputing the remaining floating point operations.
Hi Nic, While I must say it's a clever idea to cache data, I think merging this would be a really bad idea. The possibilities for screwing things up with this are just too great - there's already people sending all kind of crap to the encoder (and expecting it to work) that I don't want to introduce something that's really more complicated to understand. I think the initialization code should just be fixed-point-ized at some pint. BTW, since initialization is only run once for a channel (and running for more channels will break your hack), even float emulation will usually work fine in the mean time. As for accuracy in converting to fixed-point, I don't think it's a big issue. The two things that are still in float are the window, for which I already have a fixed-point version of cos, and the auto-correlation lag-window, which can probably be approximated very well by Taylor expansion. Jean-Marc Le lundi 26 septembre 2005 ? 17:34 +0200, Nic Roets a ?crit :> I see there are still some floating point operations left in the codec > init(ialization) code. Changing that code to fixed point is not only > difficult (due to the trigonometric functions etc) but may also degrade the > precision. > > Here is an idea whereby we can easily precompute (record) all those values > on a powerful processor and then use (replay) them on an embedded processor > / DSP. The only requirement is that 'xxx_init_xxx' should be called in > exactly the same environment in both cases (e.g. FIXED_POINT and with the > same mode or sequence of modes). > > All that's needed is to include the code segment below in one of the .h > files and wrap all those float calculations in RECOPLAY, e.g. int sqrt2 = > RECOPLAY(sqrt(2)*16384) > I've also made RECOPLAY_MARK(name) to synchronize the process. > > #ifdef RECORD > #include <stdio.h> > > extern FILE *recordFile; > > #define _RECOPLAY_FOPEN \ > if (!recordFile && (recordFile = fopen ("precompute.c", "w")) != NULL) > { \ > fprintf (recordFile, "#include \"config.h\"\n\ > #ifndef EMBEDDED\n\ > #include <stdio.h>\n\ > FILE *recordFile = NULL;\n\ > #else\n\ > int recordDefault[]={\n");\ > atexit (CloseRecordFile); \ > } \ > > #define RECOPLAY_MARK(name) { _RECOPLAY_FOPEN; \ > if (recordFile) fprintf (recordFile, "}, record"#name"[] = {\n"); \ > } > > #define RECOPLAY(x) ({ \ > int v = (x); \ > _RECOPLAY_FOPEN; \ > fprintf (recordFile, " %d,\n", v); \ > v; \ > }) > > static void CloseRecordFile (void) > { > if (recordFile) { > fprintf (recordFile, "}, *recordPtr = recordDefault;\n #endif\n"); > fclose (recordFile); > } > } > > #else /* Not recording */ > #ifndef EMBEDDED > #define RECOPLAY_MARK(x) > #define RECOPLAY(x) (x) > #else > extern int *recordPtr; > #define RECOPLAY_MARK(x) {extern int record ## x[]; recordPtr = record ## > x; } > #define RECOPLAY(x) *recordPtr++ > /* Embedded version of RECOPLAY does not evaluate 'x' */ > #endif > #endif > > _______________________________________________ > Speex-dev mailing list > Speex-dev@xiph.org > http://lists.xiph.org/mailman/listinfo/speex-dev >
Maybe Matching Threads
- Precomputing the remaining floating pointoperations.
- Setting CDR(userfield) from Macro called from feature doesn't work with cdr_mysql
- Recording the conversation with MixMonitor() ends when the call is transfered
- Continue processing AGI script after hangup
- Missing 31 DTMF tones over ZAP