在较慢的PC上PlaySound太慢了吗?

问题描述

我制作了一个程序,每当按下键盘上的一个键时,就会输出一个喀哒声。 当我在PC(使用Ryzen 3900x)和一台笔记本电脑(使用i7 8850h)上尝试该程序时,即使快速键入,它也可以毫无延迟地完美输出声音。

但是在我用于学校的较慢笔记本电脑上,它不能正确输出声音,尤其是在快速键入时。 (声音被延迟,或者在停止之前只起到了很小的作用)

除了PlaySound可能太慢或其他原因之外,我找不到其他问题。它与加载声音文件没有任何关系,因为我正在播放内存中的声音。这也不是按键的识别,因为控制台输出(按下哪个键)几乎是即时的。

这是我的代码

#ifndef UNICODE
#define UNICODE
#endif // UNICODE

#include <stdio.h>
#include <stdlib.h>
#include <w32api.h>
#define WINVER WindowsXP
#include <windows.h>
#include <winuser.h>

BYTE* byteAudio = NULL;

LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WParaM wParam,LParaM lParam)
{
    if(uMsg == WM_INPUT)
    {
        HRAWINPUT hRawInput = (HRAWINPUT)lParam;
        RAWINPUT input      = { 0 };
        UINT size           = sizeof(input);
        GetRawInputData(hRawInput,RID_INPUT,&input,&size,sizeof(RAWINPUTHEADER));

        if(input.data.keyboard.Flags == 0)
        {
            //PlaySoundW(TEXT("res/click.wav"),NULL,SND_ASYNC | SND_FILENAME);
            PlaySound(byteAudio,SND_MEMORY,SND_ASYNC | SND_MEMORY);
            printf("vkey: %x,flag: %d\n",input.data.keyboard.VKey,input.data.keyboard.Flags);
        }
    }
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpComLine,int iShowCmd)
{
    const char* CLASS_NAME = "RawInputClass";
    FILE* fPtr;
    long lFileSize;

    //Gets file size
    fPtr        = fopen("res/click.wav","rb");
    if(!fPtr)
    {
        printf("Error while opening file!");
        return -1;
    }
    fseek(fPtr,SEEK_END);
    lFileSize   = ftell(fPtr);
    rewind(fPtr);

    //Reads file into byte-Array
    byteAudio = (BYTE*)malloc(lFileSize * sizeof(BYTE));
    if(!byteAudio)
    {
        printf("byteAudio; OUT_OF_MEMORY"); //If that happens,it is probably time for an upgrade
        return -1;
    }
    fread(byteAudio,lFileSize,1,fPtr);
    fclose(fPtr);

    //Create Message-Only window

    WNDCLASS wnd        = { 0 };
    wnd.hInstance       = GetModuleHandle(NULL);
    wnd.lpfnWndProc     = WinProc;
    wnd.lpszClassName   = CLASS_NAME;

    RegisterClass(&wnd);

    HWND hWnd = CreateWindowExW(0,CLASS_NAME,TEXT("THE WINDOW IS INVISIBLE SO WHO CARES!"),HWND_MESSAGE,GetModuleHandle(NULL),NULL);
    RAWINPUTDEVICE rid = { 0 };
    rid.usUsagePage = 0x01;
    rid.usUsage = 0x06; //keyboard
    rid.dwFlags = RIDEV_INPUTSINK | RIDEV_NOLEGACY;
    rid.hwndTarget = hWnd;

    RegisterRawInputDevices(&rid,sizeof(RAWINPUTDEVICE));

    MSG msg;
    while(GetMessage(&msg,0))
    {
        TranslateMessage(&msg);
        dispatchMessage(&msg);
    }
}

解决方法

您正在使用轮询方法,该方法很慢。

while(GetMessage(&msg,NULL,0))
{
    /* stuff */
}

了解什么是中断以及这些中断的用途。这些将解决您的问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...