pa_win_util.c (4287B)
1 /* 2 * $Id$ 3 * Portable Audio I/O Library 4 * Win32 platform-specific support functions 5 * 6 * Based on the Open Source API proposed by Ross Bencina 7 * Copyright (c) 1999-2008 Ross Bencina 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining 10 * a copy of this software and associated documentation files 11 * (the "Software"), to deal in the Software without restriction, 12 * including without limitation the rights to use, copy, modify, merge, 13 * publish, distribute, sublicense, and/or sell copies of the Software, 14 * and to permit persons to whom the Software is furnished to do so, 15 * subject to the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be 18 * included in all copies or substantial portions of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 25 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 */ 28 29 /* 30 * The text above constitutes the entire PortAudio license; however, 31 * the PortAudio community also makes the following non-binding requests: 32 * 33 * Any person wishing to distribute modifications to the Software is 34 * requested to send the modifications to the original developer so that 35 * they can be incorporated into the canonical version. It is also 36 * requested that these non-binding requests be included along with the 37 * license above. 38 */ 39 40 /** @file 41 @ingroup win_src 42 43 @brief Win32 implementation of platform-specific PaUtil support functions. 44 */ 45 46 #include <windows.h> 47 48 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 49 #include <sys/timeb.h> /* for _ftime_s() */ 50 #else 51 #include <mmsystem.h> /* for timeGetTime() */ 52 #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */ 53 #pragma comment( lib, "winmm.lib" ) 54 #endif 55 #endif 56 57 #include "pa_util.h" 58 59 /* 60 Track memory allocations to avoid leaks. 61 */ 62 63 #if PA_TRACK_MEMORY 64 static int numAllocations_ = 0; 65 #endif 66 67 68 void *PaUtil_AllocateMemory( long size ) 69 { 70 void *result = GlobalAlloc( GPTR, size ); 71 72 #if PA_TRACK_MEMORY 73 if( result != NULL ) numAllocations_ += 1; 74 #endif 75 return result; 76 } 77 78 79 void PaUtil_FreeMemory( void *block ) 80 { 81 if( block != NULL ) 82 { 83 GlobalFree( block ); 84 #if PA_TRACK_MEMORY 85 numAllocations_ -= 1; 86 #endif 87 88 } 89 } 90 91 92 int PaUtil_CountCurrentlyAllocatedBlocks( void ) 93 { 94 #if PA_TRACK_MEMORY 95 return numAllocations_; 96 #else 97 return 0; 98 #endif 99 } 100 101 102 void Pa_Sleep( long msec ) 103 { 104 Sleep( msec ); 105 } 106 107 static int usePerformanceCounter_; 108 static double secondsPerTick_; 109 110 void PaUtil_InitializeClock( void ) 111 { 112 LARGE_INTEGER ticksPerSecond; 113 114 if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 ) 115 { 116 usePerformanceCounter_ = 1; 117 secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart; 118 } 119 else 120 { 121 usePerformanceCounter_ = 0; 122 } 123 } 124 125 126 double PaUtil_GetTime( void ) 127 { 128 LARGE_INTEGER time; 129 130 if( usePerformanceCounter_ ) 131 { 132 /* 133 Note: QueryPerformanceCounter has a known issue where it can skip forward 134 by a few seconds (!) due to a hardware bug on some PCI-ISA bridge hardware. 135 This is documented here: 136 http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323& 137 138 The work-arounds are not very paletable and involve querying GetTickCount 139 at every time step. 140 141 Using rdtsc is not a good option on multi-core systems. 142 143 For now we just use QueryPerformanceCounter(). It's good, most of the time. 144 */ 145 QueryPerformanceCounter( &time ); 146 return time.QuadPart * secondsPerTick_; 147 } 148 else 149 { 150 #ifndef UNDER_CE 151 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 152 return GetTickCount64() * .001; 153 #else 154 return timeGetTime() * .001; 155 #endif 156 #else 157 return GetTickCount() * .001; 158 #endif 159 } 160 }