Reading keyboard events (Windows 7) with C/C++ - c++

I saw examples from keyloggers that are working like that:
for (int i = 8; i < 191; i++) {
if (GetAsyncKeyState(i) & 1 == 1) {
cout << i << endl;
}
}
This is working, but it takes events from every keyboard that is connected to the computer (for example the standard-keyboard and a barcode-scanner).
Is there a possibility to read the events only from a specific keyboard (the barcode-scanner).
I know the function GetRawInputDeviceList(...) that list all the devices that are connected to the computer. This seems like an interesting beginning.
A simple working example would be nice :)
Edit:
I wrote a solution to the problem. It is available under this link:
https://drive.google.com/drive/folders/0BzWPIxqSSyP8fkZiaDI2c3VWNmNqSGd0aDc4TFVpLVYtbWdLdmZjMU9RUVFIMXNtY0FYdEk
It is heavily commented :)
but some of them are in German, sorry :(

Related

When received key input, output should stop streaming with a delay and put it all out at once

The famous text scrolling effect has been used in many games, and I mean many console-based-RPG games.
I'm somewhat trying to make my own as a novice project to sharpen my C++ skills, however, I got stuck somewhere.
You see, while a stream of text is scrolling, the player eventually gets bored and wants to skip those texts.
What happens is, that when the player presses a certain key, the text stops scrolling(and by scrolling I mean spitting out characters of a string with increasing index i with a slight delay) and it spits out everything at once.
This is quite the effect which I am trying to replicate.
This is the I currently use (without the skip-through effect):
for(int i = 0; i<text.length();i++)
{
std::cout << text[i];
Sleep(200);//WINAPI function for timeout. DWORD Milliseconds as argument
}
And the one that I want:
for(int i = 0; i<text.length();i++)
{
std::cout << text[i];
if(GetAsyncState(VK_RETURN)
{
continue;
}
else{
Sleep(200);//WINAPI function for timeout. DWORD Milliseconds as argument
}
}
This is very novice code, so please don't criticize me.
So I end this shtick with my question:
How to stop text from streaming with a delay, and to make it output it all at once.
Have a nice day!

How to count the times a key has been pressed in c++

I am making a game in Visual studious 2017 (visual c++), where you have to repeatedly press the space bar to earn money. But I have run into a problem, the compiler can't keep up when you press the spacebar really fast and so It miscounts. I tried doing some research, but all I got was this and as I said earlier it cant keep up.
this is so far what i got:
int click_systm()
{
char spacebar;
while (1)
{
if (GetAsyncKeyState(VK_SPACE) != 0)
{
if (GetKeyState(VK_SPACE) == 0)
{
spacebar = _getch();
int value = spacebar;
if (value == 32)
{
money++;
cout << money << endl;
}
}
}
}
}
If you made it here, thanks for taking your time to read this :)
The compiler is what compiles your C++ code into some binary. The CPU as well as the OS should be able to keep up with a human speed spacebar smashing. The problem can be from the fact that you run your soft inside a console(please see the comment left by user253751).
std::cout slows down a program by a lot because of the time it takes to print. As also mentioned it the comment, split your printing in a different thread. You can also add std::ios_base::sync_with_stdio(false); to gain some speed if you really need to.
I have found an answer to my own question, for those that have the same problem. This code here will do the same thing but is more responsive and will keep up to the button mashing.
int click_systm()
{
char spacebar;
while (1)
{
spacebar = _getch();
if (spacebar == 32)
{
money++;
cout << money << "\n";
}
}
}
Thanks to everyone trying to help me, espically MrScriptX and Antonio.

Arduino - making a ringing tone but its not accurate

Arduino, i am trying to make ring tone (like brrr brrr, brrr brrr, old common telephone ring tone), but i am not even close to it yet. Can anyone show me how you do it?
void play_on() { // this should play exact telephony ring tone, but how?
for(int i=0; i <50; i++) {
tone(2, i+900, i+10);
delay(60);
noTone(2);
}
}

ZigBee Arduino, Incorrect parsed datas

I've got some trouble to make communication between 2 arduinos Uno to work.
Arduino1<>ZigBee >---------- < ZigBee < > Arduino2
I'm currently trying to make them understand each other. The message is currently going well between the 1st Arduino to his Zigbee then to the Second Zigbee.
Arduino1<>ZigBee>----------< ZigBee--X-- Arduino2
The problem is: When I try to parse, on Arduino2 the payload of the incoming packet from the Arduino1, the messages are differents.
Since I'm using ZigBee API2, there's a CRC on the message while travelling between ZigBees so (after some investigations) I'm sure that the packet is correct where arriving on the ZigBee2 (if not, packet is dropped).
So the main event now:
memmove(received,xbee_Rx.getData(),24);
When I receive the packet
xbee.readPacket();
if (xbee.getResponse().isAvailable())
{
if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE)
{
xbee.getResponse().getZBRxResponse(xbee_Rx);
memmove(received,xbee_Rx.getData(),24);
for (int i = 0; i < 24; i++) {
Serial.print(received[i],HEX);
}
}
}
While I send this " 4144000000000000446B3AB4083E8484258 " in HEX on Arduino1
I received this " 414400000000000008C201862419B5 " in HEX on Arduino2
It's an example, datas are always wrong (apart maybe from the two first bytes). The result is kinda random and unusable for me.
I also tried to parse with
for (int i = 0; i < 24; i++) {
received[i] = xbee_Rx.getData()[i];
Serial.print(received[i],HEX);
}
but the result was kinda the same.
So my question is: Am I doing the parsing wrong? Is there a problem with the getData() function?
Thank you :-)
EDIT:
after some research, i've found that if i do
for (int i = 0; i < sizeof(xbee_Rx.getData()); i++) {
Serial.print(xbee_Rx.getData()[i],HEX);
}
Serial.println();
for (int i = 0; i < sizeof(received); i++) {
Serial.print(received[i],HEX);
}
datas are not the same.
414400000000000008C201885358C80
414400000000000008C201862419E6
instead of
4144000000000000441A6E9B407DDD494258
So, I guess while I'm reading the data is changing and that's maybe why it f**k up datas. So, is there any way to "freeze" the Datas before I read them?
I finally found what was going on:
I'm using NewSoftSerial (because one Serial is clearly not enough) and it seems to f**ck up timers (long timeout) and I was actually using either TimerOne library or the "Thread.h" library to kinda allow me to use interrupt.
Well, the whole thing was clearly messed up by the timeout on NSS so beware if you use them together in the future. I had to switch from TimerOne to Thread.h (which wasn't real threads of course), allowing me to avoid problems.
I also found that normal Serial, the one bundled with the Arduino, was playing bad stuff aswell with the timer things.
So thank you for trying to help me, but it wasn't really where I thought the problem was.
Venix

C++ ASIO, accessing buffers

I have no experience in audio programming and C++ is quite low level language so I have a little problems with it. I work with ASIO SDK 2.3 downloaded from http://www.steinberg.net/en/company/developers.html.
I am writing my own host based on example inside SDK.
For now I've managed to go through the whole sample and it looks like it's working. I have external sound card connected to my PC. I've successfully loaded driver for this device, configured it, handled callbacks, casting data from analog to digital etc. common stuff.
And part where I am stuck now:
When I play some track via my device I can see bars moving in the mixer (device's software). So device is connected in right way. In my code I've picked the inputs and outputs with the names of the bars that are moving in mixer. I've also used ASIOCreateBuffers() to create buffer for each input/output.
Now correct me if I am wrong:
When ASIOStart() is called and driver is in running state, when I input the sound signal to my external device I believe the buffers get filled with data, right?
I am reading the documentation but I am a bit lost - how can I access the data being sent by device to application, stored in INPUT buffers? Or signal? I need it for signal analysis or maybe recording in future.
EDIT: If I had made it to complicated then in a nutshell my question is: how can I access input stream data from code? I don't see any objects/callbacks letting me to do so in documentation.
The hostsample in the ASIO SDK is pretty close to what you need. In the bufferSwitchTimeInfo callback there is some code like this:
for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++)
{
int ch = asioDriverInfo.bufferInfos[i].channelNum;
if (asioDriverInfo.bufferInfos[i].isInput == ASIOTrue)
{
char* buf = asioDriver.bufferInfos[i].buffers[index];
....
Inside of that if block asioDriver.bufferInfos[i].buffers[index] is a pointer to the raw audio data (index is a parameter to the method).
The format of the buffer is dependent upon the driver and that can be discovered by testing asioDriverInfo.channelInfos[i].type. The types of formats will be 32bit int LSB first, 32bit int MSB first, and so on. You can find the list of values in the ASIOSampleType enum in asio.h. At this point you'll want to convert the samples to some common format for downstream signal processing code. If you're doing signal processing you'll probably want convert to double. The file host\asioconvertsample.cpp will give you some idea of what's involved in the conversion. The most common format you're going to encounter is probably INT32 MSB. Here is how you'd convert it to double.
for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++)
{
int ch = asioDriverInfo.bufferInfos[i].channelNum;
if (asioDriverInfo.bufferInfos[i].isInput == ASIOTrue)
{
switch (asioDriverInfo.channelInfos[i].type)
{
case ASIOInt32LSB:
{
double* pDoubleBuf = new double[_bufferSize];
for (int i = 0 ; i < _bufferSize ; ++i)
{
pDoubleBuf[i] = *(int*)asioDriverInfo.bufferInfos.buffers[index] / (double)0x7fffffff;
}
// now pDoubleBuf contains one channels worth of samples in the range of -1.0 to 1.0.
break;
}
// and so on...
Thank you very much. Your answer helped quite much but as I am inexperienced with C++ a bit :P I find it a bit problematic.
In general I've written my own host based on hostsample. I didn't implement asioDriverInfo structure and use common variables for now.
My first problem was:.
char* buf = asioDriver.bufferInfos[i].buffers[index];
as I got error that I can't cast (void*) to char* but this probably solved the problem:
char* buf = static_cast<char*>(bufferInfos[i].buffers[doubleBufferIndex]);
My second problem is with the data conversion. I've checked the file you've recommended me but I find it a little black magic. For now I am trying to follow your example and:
for (int i = 0; i < inputBuffers + outputBuffers; i++)
{
if (bufferInfos[i].isInput)
{
switch (channelInfos[i].type)
{
case ASIOSTInt32LSB:
{
double* pDoubleBuf = new double[buffSize];
for (int j = 0 ; j < buffSize ; ++j)
{
pDoubleBuf[j] = bufferInfos[i].buffers[doubleBufferIndex] / (double)0x7fffffff;
}
break;
}
}
}
I get error there:
pDoubleBuf[j] = bufferInfos[i].buffers[doubleBufferIndex] / (double)0x7fffffff;
which is:
error C2296: '/' : illegal, left operand has type 'void *'
What I don't get is that in your example there is no table there: asioDriverInfo.bufferInfos.buffers[index] after bufferInfos and even if I fix it... to what kind of type should I cast it to make it work. P
PS. I am sure ASIOSTInt32LSB data type is fine for my PC.
The ASIO input and output buffers are accessible using void pointers, but using memcpy or memmove to access I/O buffer will create a memory copy which is to be avoided if you are doing real-time processing. I would suggest casting the pointer type to int* so you can directly access them.
It's also very slow in real-time processing to cast types 1 by 1 when you have like 100+ audio channels when AVX2 is supported on most CPUs.
_mm256_loadu_si256() and _mm256_cvtepi32_ps() will do the conversion much faster.