Thread: Win32 API Speed Issues

  1. #1
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382

    Win32 API Speed Issues

    I'm trying to write a software synthesiser for Windows for a university project. The project in in the prototype stage, where I have a basic Windows interface and a graphical display (rendered using the SetPixel () function).

    The problem is, the program won't run at a sufficient speed so as to get a reasonable sample rate for the audio.

    The code to do this will go in the WM_TIMER event, and even with the timer interval set to 0, the program is still far too slow.

    How can I get the program running at a decent speed?
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  2. #2
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    You can access the higher precision counter with QueryPerformanceCounter(), but without more details of how your code is structured, it is difficult to advise how to integrate it with your code.

    You may well need to run your sampling code in a seperate thread at a higher priority then your UI if timing is critical. You will, however, have to be careful you don't make the UI so slow as to render the whole product useless.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  3. #3
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    Can you explain how to implement the high-resolution timer with QueryPerformanceCounter ()?
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    847
    Quote Originally Posted by samGwilliam
    The code to do this will go in the WM_TIMER event, and even with the timer interval set to 0, the program is still far too slow.
    I agree that this should be in another thread. While your window is being painted the WM_TIMER messages are waiting in the message queue.

  5. #5
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    Multithreading is a big mystery to me.
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I have a basic Windows interface and a graphical display (rendered using the SetPixel () function).
    SetPixel is an extremely inefficient way to render your display. If you need to manipulate pixels, a better method is to create a dib section (which gives you access to the pixel data) and BitBlt it to the window when required. This approach will be an order of magnitude faster than using SetPixel.

    You create a dib-section with the CreateDIBSection function. The following sample creates a 32bpp bitmap WIDTH x HEIGHT (WIDTH and HEIGHT are assumed to be constants defined by you) and selects it into a memory device context:
    Code:
        BITMAPINFO bmp   = { 0 };
        DWORD*     pBits = NULL;
        HBITMAP    hBmp  = NULL;
        HDC        hdcMem = NULL;
    
        bmp.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
        bmp.bmiHeader.biWidth       = WIDTH;
        bmp.bmiHeader.biHeight      = HEIGHT;
        bmp.bmiHeader.biPlanes      = 1;
        bmp.bmiHeader.biBitCount    = 32;
        bmp.bmiHeader.biCompression = BI_RGB;
    
        hBmp = CreateDIBSection(NULL, &bmp, DIB_RGB_COLORS, &pBits, NULL, 0);
        hdcMem = CreateCompatibleDC(NULL);
        SelectObject(hdcMem, hBmp);
    Then you can manipulate pixels in the bitmap. This shows how to set a pixel at x,y to blue. You could create a macro to simplify pixel indexing.
    Code:
    pBits[(y * WIDTH) + x] = RGB(0, 0, 0xFF);
    When you receive a WM_PAINT message, you need to blit the bitmap to the window:
    Code:
    case WM_PAINT:
    {
    	PAINTSTRUCT ps = { 0 };
    
    	BeginPaint(hwnd, &ps);
    
    	BitBlt(ps.hdc, 0, 0, WIDTH, HEIGHT, hdcMem, 0, 0, SRCCOPY);
    
    	EndPaint(hwnd, &ps);
    	break;
    }
    When the window needs updating, for example, after you have manipulated the pixels in your WM_TIMER handler, you should let Windows know by calling InvalidateRect. This will cause Windows to post a WM_PAINT message.
    Code:
    InvalidateRect(hwnd, NULL, FALSE);
    Last edited by anonytmouse; 12-06-2005 at 12:29 PM.

  7. #7
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> Multithreading is a big mystery to me.

    Have a read through my basic MT tutorial starting there.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  8. #8
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    This has been a big help. Thanks a lot!
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. WIN32 API and Linux... *shudder
    By parad0x13 in forum C++ Programming
    Replies: 4
    Last Post: 07-24-2008, 07:27 PM
  2. Speed issues
    By Govtcheez in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-22-2005, 03:06 AM
  3. Win32 API and MFC
    By loopshot in forum C++ Programming
    Replies: 6
    Last Post: 12-07-2004, 11:58 AM
  4. Win32 API Questions
    By CPP-Null in forum C++ Programming
    Replies: 1
    Last Post: 05-25-2003, 04:26 PM
  5. progress bars with Win32 API
    By bennyandthejets in forum C++ Programming
    Replies: 15
    Last Post: 09-10-2002, 04:25 AM