I'm trying to create a program in C++ where I play a beep sound, with a frequency and duration of the user's choice.
The program needs to continue running while playing the beep sound.
I figured out I should use multi-threading for this, but I don't have any experience with this.
For example, this is a simple program, but I get an error when I use _beginthread
:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <process.h>
using namespace std;
int freq = 0;
int sec = 0;
int mil = 0;
void beepTone(int freqq, int mill)
{
Beep(freqq, mill);
_endthread();
}
int main()
{
cout << "Frequency?" << endl;
cin >> freq;
cout << "Duration?" << endl;
cin >> sec;
mil = 1000 * sec;
_beginthread(beepTone(freq, mil), 0, NULL);
cout << "Test Threading";
return 0;
}
Argument of type "void(*)(int freqq, int mill)" is incompatible with parameter of type "_beginthread_proc_type"
I think the point of this testing program is pretty clear.
I have code that runs, but in this code I can't choose my own frequency and duration:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <process.h>
using namespace std;
void beepTone(void *arg)
{
Beep(1000, 3000);
_endthread();
}
int main()
{
_beginthread(beepTone, 0, NULL);
cout << "Test Threading";
cin.get();
return 0;
}
This one plays 1000Hz for 3 sec while continuing the program.
Can anyone help me on how can I tell the thread which frequency and duration to play?
Your first example fails to compile because you are actually calling beepTone()
and then trying to pass its void
return value to the start_address
parameter of _beginthread()
, which will not work. You need to pass beepTone()
itself to that parameter, not its return value.
Your second example is correctly passing beepTone()
itself to _beginThread()
, but is not passing any data to beepTone()
.
Now, to accomplish what you want, _beginthread()
has an arglist
parameter that you can use to pass user data to your thread function. That is what you need to use to send your beep values to the thread so it can then pass them to Beep()
.
Try something like this:
#include "stdafx.h"
#include <Windows.h>
#include <process.h>
#include <iostream>
using namespace std;
struct beepParams
{
int freq;
int mil;
};
void __cdecl beepTone(void *arg)
{
beepParams *params = static_cast<beepParams*>(arg);
Beep(params->freq, params->mil);
delete params;
_endthread();
}
int main()
{
int freq = 0, sec = 0, mil = 0;
cout << "Frequency?" << endl;
cin >> freq;
cout << "Duration?" << endl;
cin >> sec;
mil = 1000 * sec;
beepParams *params = new beepParams;
params->freq = freq;
params->mil = mil;
if (_beginthread(&beepTone, 0, params) == -1)
delete params;
cout << "Test Threading";
//...
cin.get();
return 0;
}
That being said, if you are using C++11 or later, consider using std::thread
instead:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <thread>
using namespace std;
struct beepParams
{
int freq;
int mil;
};
void beepTone(beepParams params)
{
Beep(params.freq, params.mil);
}
int main()
{
int freq = 0, sec = 0, mil = 0;
cout << "Frequency?" << endl;
cin >> freq;
cout << "Duration?" << endl;
cin >> sec;
mil = 1000 * sec;
beepParams params;
params.freq = freq;
params.mil = mil;
thread t(beepTone, params);
t.detach();
cout << "Test Threading";
//...
cin.get();
return 0;
}