Chris@69: /*********************************************************************** Chris@69: Copyright (c) 2006-2011, Skype Limited. All rights reserved. Chris@69: Redistribution and use in source and binary forms, with or without Chris@69: modification, are permitted provided that the following conditions Chris@69: are met: Chris@69: - Redistributions of source code must retain the above copyright notice, Chris@69: this list of conditions and the following disclaimer. Chris@69: - Redistributions in binary form must reproduce the above copyright Chris@69: notice, this list of conditions and the following disclaimer in the Chris@69: documentation and/or other materials provided with the distribution. Chris@69: - Neither the name of Internet Society, IETF or IETF Trust, nor the Chris@69: names of specific contributors, may be used to endorse or promote Chris@69: products derived from this software without specific prior written Chris@69: permission. Chris@69: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" Chris@69: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE Chris@69: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE Chris@69: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE Chris@69: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR Chris@69: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF Chris@69: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS Chris@69: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN Chris@69: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) Chris@69: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE Chris@69: POSSIBILITY OF SUCH DAMAGE. Chris@69: ***********************************************************************/ Chris@69: Chris@69: #ifndef SILK_DEBUG_H Chris@69: #define SILK_DEBUG_H Chris@69: Chris@69: #include "typedef.h" Chris@69: #include /* file writing */ Chris@69: #include /* strcpy, strcmp */ Chris@69: Chris@69: #ifdef __cplusplus Chris@69: extern "C" Chris@69: { Chris@69: #endif Chris@69: Chris@69: unsigned long GetHighResolutionTime(void); /* O time in usec*/ Chris@69: Chris@69: /* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping Chris@69: * intermediate signals from the codec. Chris@69: */ Chris@69: #define SILK_DEBUG 0 Chris@69: Chris@69: /* Flag for using timers */ Chris@69: #define SILK_TIC_TOC 0 Chris@69: Chris@69: Chris@69: #if SILK_TIC_TOC Chris@69: Chris@69: #if (defined(_WIN32) || defined(_WINCE)) Chris@69: #include /* timer */ Chris@69: #else /* Linux or Mac*/ Chris@69: #include Chris@69: #endif Chris@69: Chris@69: /*********************************/ Chris@69: /* timer functions for profiling */ Chris@69: /*********************************/ Chris@69: /* example: */ Chris@69: /* */ Chris@69: /* TIC(LPC) */ Chris@69: /* do_LPC(in_vec, order, acoef); // do LPC analysis */ Chris@69: /* TOC(LPC) */ Chris@69: /* */ Chris@69: /* and call the following just before exiting (from main) */ Chris@69: /* */ Chris@69: /* silk_TimerSave("silk_TimingData.txt"); */ Chris@69: /* */ Chris@69: /* results are now in silk_TimingData.txt */ Chris@69: Chris@69: void silk_TimerSave(char *file_name); Chris@69: Chris@69: /* max number of timers (in different locations) */ Chris@69: #define silk_NUM_TIMERS_MAX 50 Chris@69: /* max length of name tags in TIC(..), TOC(..) */ Chris@69: #define silk_NUM_TIMERS_MAX_TAG_LEN 30 Chris@69: Chris@69: extern int silk_Timer_nTimers; Chris@69: extern int silk_Timer_depth_ctr; Chris@69: extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; Chris@69: #ifdef _WIN32 Chris@69: extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; Chris@69: #else Chris@69: extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; Chris@69: #endif Chris@69: extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; Chris@69: extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; Chris@69: extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; Chris@69: extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; Chris@69: extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; Chris@69: Chris@69: /* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */ Chris@69: #ifdef _WIN32 Chris@69: #define TIC(TAG_NAME) { \ Chris@69: static int init = 0; \ Chris@69: static int ID = -1; \ Chris@69: if( init == 0 ) \ Chris@69: { \ Chris@69: int k; \ Chris@69: init = 1; \ Chris@69: for( k = 0; k < silk_Timer_nTimers; k++ ) { \ Chris@69: if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ Chris@69: ID = k; \ Chris@69: break; \ Chris@69: } \ Chris@69: } \ Chris@69: if (ID == -1) { \ Chris@69: ID = silk_Timer_nTimers; \ Chris@69: silk_Timer_nTimers++; \ Chris@69: silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ Chris@69: strcpy(silk_Timer_tags[ID], #TAG_NAME); \ Chris@69: silk_Timer_cnt[ID] = 0; \ Chris@69: silk_Timer_sum[ID] = 0; \ Chris@69: silk_Timer_min[ID] = 0xFFFFFFFF; \ Chris@69: silk_Timer_max[ID] = 0; \ Chris@69: } \ Chris@69: } \ Chris@69: silk_Timer_depth_ctr++; \ Chris@69: QueryPerformanceCounter(&silk_Timer_start[ID]); \ Chris@69: } Chris@69: #else Chris@69: #define TIC(TAG_NAME) { \ Chris@69: static int init = 0; \ Chris@69: static int ID = -1; \ Chris@69: if( init == 0 ) \ Chris@69: { \ Chris@69: int k; \ Chris@69: init = 1; \ Chris@69: for( k = 0; k < silk_Timer_nTimers; k++ ) { \ Chris@69: if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ Chris@69: ID = k; \ Chris@69: break; \ Chris@69: } \ Chris@69: } \ Chris@69: if (ID == -1) { \ Chris@69: ID = silk_Timer_nTimers; \ Chris@69: silk_Timer_nTimers++; \ Chris@69: silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ Chris@69: strcpy(silk_Timer_tags[ID], #TAG_NAME); \ Chris@69: silk_Timer_cnt[ID] = 0; \ Chris@69: silk_Timer_sum[ID] = 0; \ Chris@69: silk_Timer_min[ID] = 0xFFFFFFFF; \ Chris@69: silk_Timer_max[ID] = 0; \ Chris@69: } \ Chris@69: } \ Chris@69: silk_Timer_depth_ctr++; \ Chris@69: silk_Timer_start[ID] = GetHighResolutionTime(); \ Chris@69: } Chris@69: #endif Chris@69: Chris@69: #ifdef _WIN32 Chris@69: #define TOC(TAG_NAME) { \ Chris@69: LARGE_INTEGER lpPerformanceCount; \ Chris@69: static int init = 0; \ Chris@69: static int ID = 0; \ Chris@69: if( init == 0 ) \ Chris@69: { \ Chris@69: int k; \ Chris@69: init = 1; \ Chris@69: for( k = 0; k < silk_Timer_nTimers; k++ ) { \ Chris@69: if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ Chris@69: ID = k; \ Chris@69: break; \ Chris@69: } \ Chris@69: } \ Chris@69: } \ Chris@69: QueryPerformanceCounter(&lpPerformanceCount); \ Chris@69: lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \ Chris@69: if((lpPerformanceCount.QuadPart < 100000000) && \ Chris@69: (lpPerformanceCount.QuadPart >= 0)) { \ Chris@69: silk_Timer_cnt[ID]++; \ Chris@69: silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \ Chris@69: if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \ Chris@69: silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \ Chris@69: if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \ Chris@69: silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \ Chris@69: } \ Chris@69: silk_Timer_depth_ctr--; \ Chris@69: } Chris@69: #else Chris@69: #define TOC(TAG_NAME) { \ Chris@69: unsigned long endTime; \ Chris@69: static int init = 0; \ Chris@69: static int ID = 0; \ Chris@69: if( init == 0 ) \ Chris@69: { \ Chris@69: int k; \ Chris@69: init = 1; \ Chris@69: for( k = 0; k < silk_Timer_nTimers; k++ ) { \ Chris@69: if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ Chris@69: ID = k; \ Chris@69: break; \ Chris@69: } \ Chris@69: } \ Chris@69: } \ Chris@69: endTime = GetHighResolutionTime(); \ Chris@69: endTime -= silk_Timer_start[ID]; \ Chris@69: if((endTime < 100000000) && \ Chris@69: (endTime >= 0)) { \ Chris@69: silk_Timer_cnt[ID]++; \ Chris@69: silk_Timer_sum[ID] += endTime; \ Chris@69: if( endTime > silk_Timer_max[ID] ) \ Chris@69: silk_Timer_max[ID] = endTime; \ Chris@69: if( endTime < silk_Timer_min[ID] ) \ Chris@69: silk_Timer_min[ID] = endTime; \ Chris@69: } \ Chris@69: silk_Timer_depth_ctr--; \ Chris@69: } Chris@69: #endif Chris@69: Chris@69: #else /* SILK_TIC_TOC */ Chris@69: Chris@69: /* define macros as empty strings */ Chris@69: #define TIC(TAG_NAME) Chris@69: #define TOC(TAG_NAME) Chris@69: #define silk_TimerSave(FILE_NAME) Chris@69: Chris@69: #endif /* SILK_TIC_TOC */ Chris@69: Chris@69: Chris@69: #if SILK_DEBUG Chris@69: /************************************/ Chris@69: /* write data to file for debugging */ Chris@69: /************************************/ Chris@69: /* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */ Chris@69: Chris@69: #define silk_NUM_STORES_MAX 100 Chris@69: extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; Chris@69: extern int silk_debug_store_count; Chris@69: Chris@69: /* Faster way of storing the data */ Chris@69: #define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \ Chris@69: static opus_int init = 0, cnt = 0; \ Chris@69: static FILE **fp; \ Chris@69: if (init == 0) { \ Chris@69: init = 1; \ Chris@69: cnt = silk_debug_store_count++; \ Chris@69: silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \ Chris@69: } \ Chris@69: fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \ Chris@69: } Chris@69: Chris@69: /* Call this at the end of main() */ Chris@69: #define SILK_DEBUG_STORE_CLOSE_FILES { \ Chris@69: opus_int i; \ Chris@69: for( i = 0; i < silk_debug_store_count; i++ ) { \ Chris@69: fclose( silk_debug_store_fp[ i ] ); \ Chris@69: } \ Chris@69: } Chris@69: Chris@69: #else /* SILK_DEBUG */ Chris@69: Chris@69: /* define macros as empty strings */ Chris@69: #define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES) Chris@69: #define SILK_DEBUG_STORE_CLOSE_FILES Chris@69: Chris@69: #endif /* SILK_DEBUG */ Chris@69: Chris@69: #ifdef __cplusplus Chris@69: } Chris@69: #endif Chris@69: Chris@69: #endif /* SILK_DEBUG_H */