Reputation: 11
I am creating a music program in C++. When multiple keys are pressed, the sound for each key gets delayed, so I may not actively be pressing a key, but sounds are still playing. There is also a slight delay between my key press and the sound playing.
I tried to use while loops instead of if statements, but it didn't work. I want each key to play a tone, regardless of if there are other keys being pressed at the same time. I also want to get rid of the delay between key presses and music playing. Here is the code:
#include <windows.h>
#include <iostream>
int main(){
std::cout << "Welcome to MusicBox. Use keys S-L to play music.";
while (true){
if (GetAsyncKeyState('S') & 0x8000){
Beep(300, 200);
}
if (GetAsyncKeyState('D') & 0x8000){
Beep(400, 200);
}
if (GetAsyncKeyState('F') & 0x8000){
Beep(500, 200);
}
if (GetAsyncKeyState('G') & 0x8000){
Beep(600, 200);
}
if (GetAsyncKeyState('H') & 0x8000){
Beep(700, 200);
}
if (GetAsyncKeyState('J') & 0x8000){
Beep(800, 200);
}
if (GetAsyncKeyState('K') & 0x8000){
Beep(900, 200);
}
if (GetAsyncKeyState('L') & 0x8000){
Beep(1000, 200);
}
}
}
Upvotes: 1
Views: 97
Reputation: 59574
You can't play multiple tones at the same time, because:
The function is synchronous; it performs an alertable wait and does not return control to its caller until the sound finishes.
Source: Microsoft Learn, Beep(), emphasis mine
The only way to bypass this limitation was to call the method from different threads. I tried that, and unfortunately, this will only play one sound and ignore others which are played in parallel. They will not be mixed.
Minimum code (use C++20 for jthread
, a thread that will automatically join()
in the destructor):
#include <windows.h>
#include <thread>
int main() {
std::jthread a(Beep, 440, 2000);
std::jthread c(Beep, 523, 2000);
std::jthread a2(Beep, 880, 2000);
}
Depending on which thread is scheduled first by the OS, one of the three notes will be played.
Some of the comments to the question are not valid. E.g. the comment
I am not sure "Beep" still even works on all PCs. For example mine doesn't even have a beeper.
is no longer relevant since Windows 7:
In Windows 7, Beep was rewritten to pass the beep to the default sound device for the session.
Source: Microsoft Learn, Beep(), Remarks Section
OT/side node: look up actual frequencies for tones, if you want your music program to sound like a piano. An A would be 440 Hz, and frequencies are not linear, but exponential.
Upvotes: 5