DCP
DCP

Reputation: 131

How to access the PC Keyboard Buffer for Detecting multiple key press and key release?

I am making a harmonium synthesizer software for PC in C language, for that I have to detect multiple keypress and keyrelease so that to play notes simultaneously accordingly. So, I am thinking that accessing the keyboard buffer would be helpful. But I don't know how to. So can anyone suggest the method to do so or some new idea to detect multiple keypress. For detecting single keypress and keyrelease I have made following C code using kbhit() and getch() functions:-

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>

void keypress(char);
void delay(int);

int flag=0;

int main()
{
    char c;

    while(1)
    {
        if(kbhit())
        {
            c=getch();

            printf("\nCharacter:%c",c);

            getch();

            keypress(c);

            printf("\nKey Released");

        }
    }

    return 0;
}

void keypress(char ch)
{
    char c;

    delay(50);

    if(kbhit())
    {
        c=getch();

        if(c==ch)
        {
            keypress(c);
        }

    }
}

void delay(int milliSeconds)
{
    clock_t final_time = milliSeconds + clock();
    while (final_time > clock());
}

But it has some issues like:-

1).Multiple keypress not detected

2).It generates a very small delay

So can anybody suggest Improvement to code to solve the above issue or some new techniques for detecting multiple key press and key release.

Platform:-Windows 8.1

It would be good if the solution would platform friendly.

Thanks!

Upvotes: 0

Views: 1267

Answers (2)

Weather Vane
Weather Vane

Reputation: 34575

This shows how to use the Windows GetAsyncKeyState function. It does not need to be in a GUI - this console app works as shown. It will be up to you to examine the bit status flags as documented to determine action. For example, auto-repeat is honoured when a key is pressed. You probably won't need to check every key either.

#include <stdio.h>
#include <windows.h>

int main(void)
{
    unsigned short buff[256] = {0};
    unsigned short kval;
    int i;
    while (1) {
        for(i=0; i<256; i++) {
            kval = GetAsyncKeyState(i);
            if(kval != buff[i]) {
                printf("%02X:%04X ", i, kval);
                buff[i] = kval;
            }
        }
    }
    return 0;
}

In this test, the first line was output before I pressed any key. The second line was output when I pressed and released 'A'.

0D:0001 26:0001 45:0001 53:0001 54:0001 0D:0000 26:0000 45:0000 53:0000 54:0000
41:8001 41:8000 41:0000

Note: linked with user32.lib.

Upvotes: 1

Serge Ballesta
Serge Ballesta

Reputation: 148870

As you include conio.h, the solution is already tied to a Windows (or MS/DOS) platform.

Here as i assume you do not really need a command line program, the best way would be build a Windows GUI program having an event loop and directly processing the WM_KEYDOWN and WM_KEYUP messages to be alerted as soon as a key is pressed on released on the keyboard. To avoid any risk of loosing one change in the state of the key, you could even consistently use the GetKeyboardState API function to load the current state of all keys on the keyboard.

I know this is more a hint that a precise answer, but a detailed answer would be much too long for a SO post.

Upvotes: 1

Related Questions