]> Repos - portaudio/commitdiff
improved PaWasapi_ThreadPriorityBoost by providing enum PaWasapiThreadPriority with...
authordmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Wed, 17 Feb 2010 10:11:40 +0000 (10:11 +0000)
committerdmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Wed, 17 Feb 2010 10:11:40 +0000 (10:11 +0000)
include/pa_win_wasapi.h
src/hostapi/wasapi/pa_win_wasapi.cpp

index 1d26a2e68a7d978f4365b33996f73a1f524af92e..9023ff163d0ea6a7ccdd27be66c8177258f52afe 100644 (file)
@@ -68,12 +68,17 @@ typedef enum PaWasapiFlags
        Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling\r
              method can only provide 15-20ms latency. */\r
     paWinWasapiPolling                  = (1 << 3),\r
+\r
+    /* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority \r
+       is set to custom value. */\r
+    paWinWasapiThreadPriority           = (1 << 4)\r
 }\r
 PaWasapiFlags;\r
 #define paWinWasapiExclusive             (paWinWasapiExclusive)\r
 #define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor)\r
 #define paWinWasapiUseChannelMask        (paWinWasapiUseChannelMask)\r
 #define paWinWasapiPolling               (paWinWasapiPolling)\r
+#define paWinWasapiThreadPriority        (paWinWasapiThreadPriority)\r
 \r
 \r
 /* Host processor. Allows to skip internal PA processing completely. \r
@@ -86,6 +91,39 @@ typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer,  long inputFra
                                                void *outputBuffer, long outputFrames,\r
                                                void *userData);\r
 \r
+/* Device role */\r
+typedef enum PaWasapiDeviceRole\r
+{\r
+    eRoleRemoteNetworkDevice = 0,\r
+    eRoleSpeakers,\r
+    eRoleLineLevel,\r
+    eRoleHeadphones,\r
+    eRoleMicrophone,\r
+    eRoleHeadset,\r
+    eRoleHandset,\r
+    eRoleUnknownDigitalPassthrough,\r
+    eRoleSPDIF,\r
+    eRoleHDMI,\r
+    eRoleUnknownFormFactor\r
+}\r
+PaWasapiDeviceRole;\r
+\r
+\r
+/* Thread priority */\r
+typedef enum PaWasapiThreadPriority\r
+{\r
+    eThreadPriorityNone = 0,\r
+    eThreadPriorityAudio,            //!< Default for Shared mode.\r
+    eThreadPriorityCapture,\r
+    eThreadPriorityDistribution,\r
+    eThreadPriorityGames,\r
+    eThreadPriorityPlayback,\r
+    eThreadPriorityProAudio,        //!< Default for Exclusive mode.\r
+    eThreadPriorityWindowManager\r
+}\r
+PaWasapiThreadPriority;\r
+\r
+\r
 /* Stream descriptor. */\r
 typedef struct PaWasapiStreamInfo \r
 {\r
@@ -98,16 +136,27 @@ typedef struct PaWasapiStreamInfo
     /* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains\r
        paWinWasapiUseChannelMask this allows you to specify which speakers \r
        to address in a multichannel stream. Constants for channelMask\r
-       are specified in pa_win_waveformat.h\r
+       are specified in pa_win_waveformat.h. Will be used only if \r
+       paWinWasapiUseChannelMask flag is specified.\r
     */\r
     PaWinWaveFormatChannelMask channelMask;\r
 \r
     /* Delivers raw data to callback obtained from GetBuffer() methods skipping \r
        internal PortAudio processing inventory completely. userData parameter will \r
-       be the same that was passed to Pa_OpenStream method.\r
+       be the same that was passed to Pa_OpenStream method. Will be used only if \r
+       paWinWasapiRedirectHostProcessor flag is specified.\r
     */\r
     PaWasapiHostProcessorCallback hostProcessorOutput;\r
     PaWasapiHostProcessorCallback hostProcessorInput;\r
+\r
+    /* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag\r
+       is specified.\r
+\r
+       Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode)\r
+       you shall specify same value for threadPriority or othervise one of the values will be used\r
+       to setup thread priority.\r
+    */\r
+    PaWasapiThreadPriority threadPriority;\r
 } \r
 PaWasapiStreamInfo;\r
 \r
@@ -123,25 +172,7 @@ PaWasapiStreamInfo;
          or, a PaErrorCode (which are always negative) if PortAudio is not initialized\r
          or an error is encountered.\r
 */\r
-int PaWasapi_GetDeviceDefaultFormat( void *pFormat, int nFormatSize, PaDeviceIndex nDevice );\r
-\r
-\r
-/* Device role */\r
-typedef enum PaWasapiDeviceRole\r
-{\r
-    eRoleRemoteNetworkDevice = 0,\r
-    eRoleSpeakers,\r
-    eRoleLineLevel,\r
-    eRoleHeadphones,\r
-    eRoleMicrophone,\r
-    eRoleHeadset,\r
-    eRoleHandset,\r
-    eRoleUnknownDigitalPassthrough,\r
-    eRoleSPDIF,\r
-    eRoleHDMI,\r
-    eRoleUnknownFormFactor\r
-}\r
-PaWasapiDeviceRole;\r
+int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice );\r
 \r
 \r
 /** Returns device role (PaWasapiDeviceRole enum).\r
@@ -160,18 +191,13 @@ int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice );
  @param hTask a handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority\r
               method to revert thread priority to initial state.\r
 \r
- @param nPriorityClass an Id of thread priority:    1 - Audio\r
-                                                    2 - Capture\r
-                                                    3 - Distribution\r
-                                                    4 - Games\r
-                                                    5 - Playback\r
-                                                    6 - Pro Audio\r
-                                                    7 - Window Manager\r
+ @param nPriorityClass an Id of thread priority of PaWasapiThreadPriority type. Specifying \r
+                       eThreadPriorityNone does nothing.\r
 \r
  @return Error code indicating success or failure.\r
  @see PaWasapi_RevertThreadPriority\r
 */\r
-PaError PaWasapi_ThreadPriorityBoost( void **hTask, int nPriorityClass );\r
+PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass );\r
 \r
 \r
 /** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread\r
index 33ae296d02a7f7f091be2c6e9c8a8f111290a60d..86b0267f764f703a4444a25a3de95a3304c91800 100644 (file)
@@ -97,6 +97,8 @@ PA_THREAD_FUNC ProcThreadPoll(void *param);
 \r
 enum { S_INPUT = 0, S_OUTPUT, S_COUNT };\r
 \r
+#define STATIC_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))\r
+\r
 #define PRINT(x) PA_DEBUG(x);\r
 \r
 #define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \\r
@@ -315,6 +317,9 @@ typedef struct PaWasapiStream
 \r
        // Av Task (MM thread management)\r
        HANDLE hAvTask;\r
+\r
+       // Thread priority level\r
+       PaWasapiThreadPriority nThreadPriority;\r
 }\r
 PaWasapiStream;\r
 \r
@@ -893,7 +898,7 @@ static inline PaWasapiHostApiRepresentation *GetHostApi(PaError *_error = NULL)
 }\r
 \r
 // ------------------------------------------------------------------------------------------\r
-int PaWasapi_GetDeviceDefaultFormat( void *pFormat, int nFormatSize, PaDeviceIndex nDevice )\r
+int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice )\r
 {\r
        if (pFormat == NULL)\r
                return paBadBufferPtr;\r
@@ -907,10 +912,10 @@ int PaWasapi_GetDeviceDefaultFormat( void *pFormat, int nFormatSize, PaDeviceInd
        if (paWasapi == NULL)\r
                return ret;\r
 \r
-       if (nDevice >= (int)paWasapi->deviceCount)\r
+       if ((UINT32)nDevice >= paWasapi->deviceCount)\r
                return paInvalidDevice;\r
 \r
-       int size = min(nFormatSize, sizeof(paWasapi->devInfo[ nDevice ].DefaultFormat));\r
+       UINT32 size = min(nFormatSize, (UINT32)sizeof(paWasapi->devInfo[ nDevice ].DefaultFormat));\r
        memcpy(pFormat, &paWasapi->devInfo[ nDevice ].DefaultFormat, size);\r
 \r
        return size;\r
@@ -1560,6 +1565,9 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
         goto error;\r
     }\r
 \r
+       // Default thread priority is Audio: for exclusive mode we will use Pro Audio.\r
+       stream->nThreadPriority = eThreadPriorityAudio;\r
+\r
        // Try create device: Input\r
        if (inputParameters != NULL)\r
     {\r
@@ -1572,7 +1580,20 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
                // Select Exclusive/Shared mode\r
                stream->in.shareMode = AUDCLNT_SHAREMODE_SHARED;\r
         if ((inputStreamInfo != NULL) && (inputStreamInfo->flags & paWinWasapiExclusive))\r
+               {\r
+                       // Boost thread priority\r
+                       stream->nThreadPriority = eThreadPriorityProAudio;\r
+                       // Make Exclusive\r
                        stream->in.shareMode = AUDCLNT_SHAREMODE_EXCLUSIVE;\r
+               }\r
+\r
+               // If user provided explicit thread priority level, use it\r
+        if ((inputStreamInfo != NULL) && (inputStreamInfo->flags & paWinWasapiThreadPriority))\r
+               {\r
+                       if ((inputStreamInfo->threadPriority > eThreadPriorityNone) &&\r
+                               (inputStreamInfo->threadPriority <= eThreadPriorityWindowManager))\r
+                               stream->nThreadPriority = inputStreamInfo->threadPriority;\r
+               }\r
 \r
                // Choose processing mode\r
                stream->in.streamFlags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;\r
@@ -1661,7 +1682,20 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
                // Select Exclusive/Shared mode\r
                stream->out.shareMode = AUDCLNT_SHAREMODE_SHARED;\r
         if ((outputStreamInfo != NULL) && (outputStreamInfo->flags & paWinWasapiExclusive))\r
+               {\r
+                       // Boost thread priority\r
+                       stream->nThreadPriority = eThreadPriorityProAudio;\r
+                       // Make Exclusive\r
                        stream->out.shareMode = AUDCLNT_SHAREMODE_EXCLUSIVE;\r
+               }\r
+\r
+               // If user provided explicit thread priority level, use it\r
+        if ((outputStreamInfo != NULL) && (outputStreamInfo->flags & paWinWasapiThreadPriority))\r
+               {\r
+                       if ((outputStreamInfo->threadPriority > eThreadPriorityNone) &&\r
+                               (outputStreamInfo->threadPriority <= eThreadPriorityWindowManager))\r
+                               stream->nThreadPriority = outputStreamInfo->threadPriority;\r
+               }\r
 \r
                // Choose processing mode\r
                stream->out.streamFlags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;\r
@@ -2440,13 +2474,14 @@ void MMCSS_deactivate(HANDLE hTask)
 }\r
 \r
 // ------------------------------------------------------------------------------------------\r
-PaError PaWasapi_ThreadPriorityBoost(void **hTask, int nPriorityClass)\r
+PaError PaWasapi_ThreadPriorityBoost(void **hTask, PaWasapiThreadPriority nPriorityClass)\r
 {\r
        if (hTask == NULL)\r
                return paUnanticipatedHostError;\r
 \r
-       static const char *mmcs_name[7] = \r
+       static const char *mmcs_name[] = \r
        {\r
+               NULL,\r
                "Audio",\r
                "Capture",\r
                "Distribution",\r
@@ -2455,7 +2490,7 @@ PaError PaWasapi_ThreadPriorityBoost(void **hTask, int nPriorityClass)
                "Pro Audio",\r
                "Window Manager"\r
        };\r
-       if ((UINT32)nPriorityClass >= 7)\r
+       if ((UINT32)nPriorityClass >= STATIC_ARRAY_SIZE(mmcs_name))\r
                return paUnanticipatedHostError;\r
 \r
        HANDLE task = MMCSS_activate(mmcs_name[nPriorityClass]);\r
@@ -2546,7 +2581,7 @@ void _OnStreamStop(PaWasapiStream *stream)
        // Restore thread priority\r
        if (stream->hAvTask != NULL)\r
        {\r
-               MMCSS_deactivate(stream->hAvTask);\r
+               PaWasapi_ThreadPriorityRevert(stream->hAvTask);\r
                stream->hAvTask = NULL;\r
        }\r
 \r
@@ -2584,7 +2619,8 @@ PA_THREAD_FUNC ProcThreadEvent(void *param)
        }\r
 \r
        // Boost thread priority\r
-       stream->hAvTask = MMCSS_activate("Pro Audio");\r
+       stream->hAvTask = NULL;\r
+       PaWasapi_ThreadPriorityBoost((void **)&stream->hAvTask, stream->nThreadPriority);\r
 \r
        // Initialize event & start INPUT stream\r
        if (stream->in.client)\r
@@ -2693,7 +2729,8 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
     processor[S_OUTPUT] = (stream->hostProcessOverrideOutput.processor != NULL ? stream->hostProcessOverrideOutput : defaultProcessor);\r
 \r
        // Boost thread priority\r
-       stream->hAvTask = MMCSS_activate("Pro Audio");\r
+       stream->hAvTask = NULL;\r
+       PaWasapi_ThreadPriorityBoost((void **)&stream->hAvTask, stream->nThreadPriority);\r
 \r
        // Initialize event & start INPUT stream\r
        if (stream->in.client)\r