1*a58d3d2aSXin Li /*********************************************************************** 2*a58d3d2aSXin Li Copyright (c) 2006-2011, Skype Limited. All rights reserved. 3*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without 4*a58d3d2aSXin Li modification, are permitted provided that the following conditions 5*a58d3d2aSXin Li are met: 6*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright notice, 7*a58d3d2aSXin Li this list of conditions and the following disclaimer. 8*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright 9*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the 10*a58d3d2aSXin Li documentation and/or other materials provided with the distribution. 11*a58d3d2aSXin Li - Neither the name of Internet Society, IETF or IETF Trust, nor the 12*a58d3d2aSXin Li names of specific contributors, may be used to endorse or promote 13*a58d3d2aSXin Li products derived from this software without specific prior written 14*a58d3d2aSXin Li permission. 15*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16*a58d3d2aSXin Li AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*a58d3d2aSXin Li IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*a58d3d2aSXin Li ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19*a58d3d2aSXin Li LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*a58d3d2aSXin Li CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*a58d3d2aSXin Li SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*a58d3d2aSXin Li INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*a58d3d2aSXin Li CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*a58d3d2aSXin Li ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*a58d3d2aSXin Li POSSIBILITY OF SUCH DAMAGE. 26*a58d3d2aSXin Li ***********************************************************************/ 27*a58d3d2aSXin Li 28*a58d3d2aSXin Li #ifndef SILK_DEBUG_H 29*a58d3d2aSXin Li #define SILK_DEBUG_H 30*a58d3d2aSXin Li 31*a58d3d2aSXin Li /* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping 32*a58d3d2aSXin Li * intermediate signals from the codec. 33*a58d3d2aSXin Li */ 34*a58d3d2aSXin Li #define SILK_DEBUG 0 35*a58d3d2aSXin Li 36*a58d3d2aSXin Li /* Flag for using timers */ 37*a58d3d2aSXin Li #define SILK_TIC_TOC 0 38*a58d3d2aSXin Li 39*a58d3d2aSXin Li #if SILK_DEBUG || SILK_TIC_TOC 40*a58d3d2aSXin Li #include "typedef.h" 41*a58d3d2aSXin Li #include <string.h> /* strcpy, strcmp */ 42*a58d3d2aSXin Li #include <stdio.h> /* file writing */ 43*a58d3d2aSXin Li #endif 44*a58d3d2aSXin Li 45*a58d3d2aSXin Li #ifdef __cplusplus 46*a58d3d2aSXin Li extern "C" 47*a58d3d2aSXin Li { 48*a58d3d2aSXin Li #endif 49*a58d3d2aSXin Li 50*a58d3d2aSXin Li #if SILK_TIC_TOC 51*a58d3d2aSXin Li 52*a58d3d2aSXin Li unsigned long GetHighResolutionTime(void); /* O time in usec*/ 53*a58d3d2aSXin Li 54*a58d3d2aSXin Li #if (defined(_WIN32) || defined(_WINCE)) 55*a58d3d2aSXin Li #include <windows.h> /* timer */ 56*a58d3d2aSXin Li #else /* Linux or Mac*/ 57*a58d3d2aSXin Li #include <sys/time.h> 58*a58d3d2aSXin Li #endif 59*a58d3d2aSXin Li 60*a58d3d2aSXin Li /*********************************/ 61*a58d3d2aSXin Li /* timer functions for profiling */ 62*a58d3d2aSXin Li /*********************************/ 63*a58d3d2aSXin Li /* example: */ 64*a58d3d2aSXin Li /* */ 65*a58d3d2aSXin Li /* TIC(LPC) */ 66*a58d3d2aSXin Li /* do_LPC(in_vec, order, acoef); // do LPC analysis */ 67*a58d3d2aSXin Li /* TOC(LPC) */ 68*a58d3d2aSXin Li /* */ 69*a58d3d2aSXin Li /* and call the following just before exiting (from main) */ 70*a58d3d2aSXin Li /* */ 71*a58d3d2aSXin Li /* silk_TimerSave("silk_TimingData.txt"); */ 72*a58d3d2aSXin Li /* */ 73*a58d3d2aSXin Li /* results are now in silk_TimingData.txt */ 74*a58d3d2aSXin Li 75*a58d3d2aSXin Li void silk_TimerSave(char *file_name); 76*a58d3d2aSXin Li 77*a58d3d2aSXin Li /* max number of timers (in different locations) */ 78*a58d3d2aSXin Li #define silk_NUM_TIMERS_MAX 50 79*a58d3d2aSXin Li /* max length of name tags in TIC(..), TOC(..) */ 80*a58d3d2aSXin Li #define silk_NUM_TIMERS_MAX_TAG_LEN 30 81*a58d3d2aSXin Li 82*a58d3d2aSXin Li extern int silk_Timer_nTimers; 83*a58d3d2aSXin Li extern int silk_Timer_depth_ctr; 84*a58d3d2aSXin Li extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; 85*a58d3d2aSXin Li #ifdef _WIN32 86*a58d3d2aSXin Li extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; 87*a58d3d2aSXin Li #else 88*a58d3d2aSXin Li extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; 89*a58d3d2aSXin Li #endif 90*a58d3d2aSXin Li extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; 91*a58d3d2aSXin Li extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; 92*a58d3d2aSXin Li extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; 93*a58d3d2aSXin Li extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; 94*a58d3d2aSXin Li extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; 95*a58d3d2aSXin Li 96*a58d3d2aSXin Li /* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */ 97*a58d3d2aSXin Li #ifdef _WIN32 98*a58d3d2aSXin Li #define TIC(TAG_NAME) { \ 99*a58d3d2aSXin Li static int init = 0; \ 100*a58d3d2aSXin Li static int ID = -1; \ 101*a58d3d2aSXin Li if( init == 0 ) \ 102*a58d3d2aSXin Li { \ 103*a58d3d2aSXin Li int k; \ 104*a58d3d2aSXin Li init = 1; \ 105*a58d3d2aSXin Li for( k = 0; k < silk_Timer_nTimers; k++ ) { \ 106*a58d3d2aSXin Li if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ 107*a58d3d2aSXin Li ID = k; \ 108*a58d3d2aSXin Li break; \ 109*a58d3d2aSXin Li } \ 110*a58d3d2aSXin Li } \ 111*a58d3d2aSXin Li if (ID == -1) { \ 112*a58d3d2aSXin Li ID = silk_Timer_nTimers; \ 113*a58d3d2aSXin Li silk_Timer_nTimers++; \ 114*a58d3d2aSXin Li silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ 115*a58d3d2aSXin Li strcpy(silk_Timer_tags[ID], #TAG_NAME); \ 116*a58d3d2aSXin Li silk_Timer_cnt[ID] = 0; \ 117*a58d3d2aSXin Li silk_Timer_sum[ID] = 0; \ 118*a58d3d2aSXin Li silk_Timer_min[ID] = 0xFFFFFFFF; \ 119*a58d3d2aSXin Li silk_Timer_max[ID] = 0; \ 120*a58d3d2aSXin Li } \ 121*a58d3d2aSXin Li } \ 122*a58d3d2aSXin Li silk_Timer_depth_ctr++; \ 123*a58d3d2aSXin Li QueryPerformanceCounter(&silk_Timer_start[ID]); \ 124*a58d3d2aSXin Li } 125*a58d3d2aSXin Li #else 126*a58d3d2aSXin Li #define TIC(TAG_NAME) { \ 127*a58d3d2aSXin Li static int init = 0; \ 128*a58d3d2aSXin Li static int ID = -1; \ 129*a58d3d2aSXin Li if( init == 0 ) \ 130*a58d3d2aSXin Li { \ 131*a58d3d2aSXin Li int k; \ 132*a58d3d2aSXin Li init = 1; \ 133*a58d3d2aSXin Li for( k = 0; k < silk_Timer_nTimers; k++ ) { \ 134*a58d3d2aSXin Li if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ 135*a58d3d2aSXin Li ID = k; \ 136*a58d3d2aSXin Li break; \ 137*a58d3d2aSXin Li } \ 138*a58d3d2aSXin Li } \ 139*a58d3d2aSXin Li if (ID == -1) { \ 140*a58d3d2aSXin Li ID = silk_Timer_nTimers; \ 141*a58d3d2aSXin Li silk_Timer_nTimers++; \ 142*a58d3d2aSXin Li silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ 143*a58d3d2aSXin Li strcpy(silk_Timer_tags[ID], #TAG_NAME); \ 144*a58d3d2aSXin Li silk_Timer_cnt[ID] = 0; \ 145*a58d3d2aSXin Li silk_Timer_sum[ID] = 0; \ 146*a58d3d2aSXin Li silk_Timer_min[ID] = 0xFFFFFFFF; \ 147*a58d3d2aSXin Li silk_Timer_max[ID] = 0; \ 148*a58d3d2aSXin Li } \ 149*a58d3d2aSXin Li } \ 150*a58d3d2aSXin Li silk_Timer_depth_ctr++; \ 151*a58d3d2aSXin Li silk_Timer_start[ID] = GetHighResolutionTime(); \ 152*a58d3d2aSXin Li } 153*a58d3d2aSXin Li #endif 154*a58d3d2aSXin Li 155*a58d3d2aSXin Li #ifdef _WIN32 156*a58d3d2aSXin Li #define TOC(TAG_NAME) { \ 157*a58d3d2aSXin Li LARGE_INTEGER lpPerformanceCount; \ 158*a58d3d2aSXin Li static int init = 0; \ 159*a58d3d2aSXin Li static int ID = 0; \ 160*a58d3d2aSXin Li if( init == 0 ) \ 161*a58d3d2aSXin Li { \ 162*a58d3d2aSXin Li int k; \ 163*a58d3d2aSXin Li init = 1; \ 164*a58d3d2aSXin Li for( k = 0; k < silk_Timer_nTimers; k++ ) { \ 165*a58d3d2aSXin Li if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ 166*a58d3d2aSXin Li ID = k; \ 167*a58d3d2aSXin Li break; \ 168*a58d3d2aSXin Li } \ 169*a58d3d2aSXin Li } \ 170*a58d3d2aSXin Li } \ 171*a58d3d2aSXin Li QueryPerformanceCounter(&lpPerformanceCount); \ 172*a58d3d2aSXin Li lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \ 173*a58d3d2aSXin Li if((lpPerformanceCount.QuadPart < 100000000) && \ 174*a58d3d2aSXin Li (lpPerformanceCount.QuadPart >= 0)) { \ 175*a58d3d2aSXin Li silk_Timer_cnt[ID]++; \ 176*a58d3d2aSXin Li silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \ 177*a58d3d2aSXin Li if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \ 178*a58d3d2aSXin Li silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \ 179*a58d3d2aSXin Li if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \ 180*a58d3d2aSXin Li silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \ 181*a58d3d2aSXin Li } \ 182*a58d3d2aSXin Li silk_Timer_depth_ctr--; \ 183*a58d3d2aSXin Li } 184*a58d3d2aSXin Li #else 185*a58d3d2aSXin Li #define TOC(TAG_NAME) { \ 186*a58d3d2aSXin Li unsigned long endTime; \ 187*a58d3d2aSXin Li static int init = 0; \ 188*a58d3d2aSXin Li static int ID = 0; \ 189*a58d3d2aSXin Li if( init == 0 ) \ 190*a58d3d2aSXin Li { \ 191*a58d3d2aSXin Li int k; \ 192*a58d3d2aSXin Li init = 1; \ 193*a58d3d2aSXin Li for( k = 0; k < silk_Timer_nTimers; k++ ) { \ 194*a58d3d2aSXin Li if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ 195*a58d3d2aSXin Li ID = k; \ 196*a58d3d2aSXin Li break; \ 197*a58d3d2aSXin Li } \ 198*a58d3d2aSXin Li } \ 199*a58d3d2aSXin Li } \ 200*a58d3d2aSXin Li endTime = GetHighResolutionTime(); \ 201*a58d3d2aSXin Li endTime -= silk_Timer_start[ID]; \ 202*a58d3d2aSXin Li if((endTime < 100000000) && \ 203*a58d3d2aSXin Li (endTime >= 0)) { \ 204*a58d3d2aSXin Li silk_Timer_cnt[ID]++; \ 205*a58d3d2aSXin Li silk_Timer_sum[ID] += endTime; \ 206*a58d3d2aSXin Li if( endTime > silk_Timer_max[ID] ) \ 207*a58d3d2aSXin Li silk_Timer_max[ID] = endTime; \ 208*a58d3d2aSXin Li if( endTime < silk_Timer_min[ID] ) \ 209*a58d3d2aSXin Li silk_Timer_min[ID] = endTime; \ 210*a58d3d2aSXin Li } \ 211*a58d3d2aSXin Li silk_Timer_depth_ctr--; \ 212*a58d3d2aSXin Li } 213*a58d3d2aSXin Li #endif 214*a58d3d2aSXin Li 215*a58d3d2aSXin Li #else /* SILK_TIC_TOC */ 216*a58d3d2aSXin Li 217*a58d3d2aSXin Li /* define macros as empty strings */ 218*a58d3d2aSXin Li #define TIC(TAG_NAME) 219*a58d3d2aSXin Li #define TOC(TAG_NAME) 220*a58d3d2aSXin Li #define silk_TimerSave(FILE_NAME) 221*a58d3d2aSXin Li 222*a58d3d2aSXin Li #endif /* SILK_TIC_TOC */ 223*a58d3d2aSXin Li 224*a58d3d2aSXin Li 225*a58d3d2aSXin Li #if SILK_DEBUG 226*a58d3d2aSXin Li /************************************/ 227*a58d3d2aSXin Li /* write data to file for debugging */ 228*a58d3d2aSXin Li /************************************/ 229*a58d3d2aSXin Li /* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */ 230*a58d3d2aSXin Li 231*a58d3d2aSXin Li #define silk_NUM_STORES_MAX 100 232*a58d3d2aSXin Li extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; 233*a58d3d2aSXin Li extern int silk_debug_store_count; 234*a58d3d2aSXin Li 235*a58d3d2aSXin Li /* Faster way of storing the data */ 236*a58d3d2aSXin Li #define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \ 237*a58d3d2aSXin Li static opus_int init = 0, cnt = 0; \ 238*a58d3d2aSXin Li static FILE **fp; \ 239*a58d3d2aSXin Li if (init == 0) { \ 240*a58d3d2aSXin Li init = 1; \ 241*a58d3d2aSXin Li cnt = silk_debug_store_count++; \ 242*a58d3d2aSXin Li silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \ 243*a58d3d2aSXin Li } \ 244*a58d3d2aSXin Li fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \ 245*a58d3d2aSXin Li } 246*a58d3d2aSXin Li 247*a58d3d2aSXin Li /* Call this at the end of main() */ 248*a58d3d2aSXin Li #define SILK_DEBUG_STORE_CLOSE_FILES { \ 249*a58d3d2aSXin Li opus_int i; \ 250*a58d3d2aSXin Li for( i = 0; i < silk_debug_store_count; i++ ) { \ 251*a58d3d2aSXin Li fclose( silk_debug_store_fp[ i ] ); \ 252*a58d3d2aSXin Li } \ 253*a58d3d2aSXin Li } 254*a58d3d2aSXin Li 255*a58d3d2aSXin Li #else /* SILK_DEBUG */ 256*a58d3d2aSXin Li 257*a58d3d2aSXin Li /* define macros as empty strings */ 258*a58d3d2aSXin Li #define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES) 259*a58d3d2aSXin Li #define SILK_DEBUG_STORE_CLOSE_FILES 260*a58d3d2aSXin Li 261*a58d3d2aSXin Li #endif /* SILK_DEBUG */ 262*a58d3d2aSXin Li 263*a58d3d2aSXin Li #ifdef __cplusplus 264*a58d3d2aSXin Li } 265*a58d3d2aSXin Li #endif 266*a58d3d2aSXin Li 267*a58d3d2aSXin Li #endif /* SILK_DEBUG_H */ 268