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