Я пытался написать функцию Beep, используя OpenAl. Но только несколько потоков функции могут быть запущены. Следующий код завершается ошибкой через некоторое время:
#include <cmath>
#include <iostream>
#include <thread>
using namespace std;
#include <AL/alut.h> // OpenAlvoid init_al()
{
const char *defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
ALCdevice* dev = alcOpenDevice(defname);
ALCcontext *ctx = alcCreateContext(dev, NULL);
alcMakeContextCurrent(ctx);
}
void exit_al()
{
ALCcontext* ctx = alcGetCurrentContext();
ALCdevice* dev = alcGetContextsDevice(ctx);
alcMakeContextCurrent(0);
alcDestroyContext(ctx);
alcCloseDevice(dev);
}
void Beep(float freq = 440, float seconds = 0.5)
{
init_al();
ALuint buf;
alGenBuffers(1, &buf);
unsigned sample_rate = 10000;
size_t buf_size = seconds * sample_rate;
short* samples = new short[buf_size];
if(samples == 0)
{
cout<< "It seems there is no more heap memory. Sorry we cannot make a beep!";
}
for(unsigned i = 0; i < buf_size; i++)
samples[i] = 32760*sin(2*M_PI*i*freq/sample_rate);
alBufferData(buf,AL_FORMAT_MONO16,samples,buf_size,sample_rate);
ALuint src;
alGenSources(1,&src);
alSourcei(src,AL_BUFFER,buf);
alSourcePlay(src);
alutSleep(seconds + 0.5);
delete[] samples;
exit_al();
}
int main()
{
for(int i = 1; i < 1000; i++)
{
thread t(Beep, 440,0.5);
t.detach();
alutSleep(0.01);
}
}
Что случилось с Beep
функционировать? И как я могу это исправить?
Я использовал это Beep
функционировать в обычной программе, где возникла проблема. Я воспроизвел ошибку в программе выше. Проблема в том, что Beeb
через некоторое время перестает отвечать, даже если вы оставляете его в покое на несколько секунд для выполнения своих предыдущих задач. Так что он использует что-то и не возвращает это. Если вы измените 1000 на 20, ничего не изменится.
Я добавил 3 новые строки в программу и разместил init_al
а также exit_al
в main
и похоже проблема решена сейчас. Кстати, я не знаю, почему это необходимо разместить init_al
а также exit_al
в main
так что это только частичный ответ на вопрос:
#include <cmath>
#include <iostream>
#include <thread>
using namespace std;
#include <AL/alut.h> // OpenAlvoid init_al()
{
const char *defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
ALCdevice* dev = alcOpenDevice(defname);
ALCcontext *ctx = alcCreateContext(dev, NULL);
alcMakeContextCurrent(ctx);
}
void exit_al()
{
ALCcontext* ctx = alcGetCurrentContext();
ALCdevice* dev = alcGetContextsDevice(ctx);
alcMakeContextCurrent(0);
alcDestroyContext(ctx);
alcCloseDevice(dev);
}
void Beep(float freq = 440, float seconds = 0.5)
{
ALuint buf;
alGenBuffers(1, &buf);
unsigned sample_rate = 10000;
size_t buf_size = seconds * sample_rate;
short* samples = new short[buf_size];
if(samples == 0)
{
cout<< "It seems there is no more heap memory. Sorry we cannot make a beep!";
}
for(unsigned i = 0; i < buf_size; i++)
samples[i] = 32760*sin(2*M_PI*i*freq/sample_rate);
alBufferData(buf,AL_FORMAT_MONO16,samples,buf_size,sample_rate);
ALuint src;
alGenSources(1,&src);
alSourcei(src,AL_BUFFER,buf);
alSourcePlay(src);
alutSleep(seconds + 0.5);
delete[] samples;
alSourceStopv(1,&src); // new line
alDeleteSources(1,&src); // new line
alDeleteBuffers(1,&buf); // new line
}
int main()
{
init_al();
for(int i = 1; i < 1000; i++)
{
thread t(Beep, 440,0.5);
t.detach();
alutSleep(0.01);
cout<< i << "\n";
}
exit_al();
}