C++ OpenAl Beep函数因线程数增加而失败
我试着用OpenAl编写一个Beep函数。但该函数只能运行几个线程。以下代码在一段时间后失败:C++ OpenAl Beep函数因线程数增加而失败,c++,c++11,openal,beep,C++,C++11,Openal,Beep,我试着用OpenAl编写一个Beep函数。但该函数只能运行几个线程。以下代码在一段时间后失败: #include <cmath> #include <iostream> #include <thread> using namespace std; #include <AL/alut.h> // OpenAl void init_al() { const char *defname = alcGetString(NULL, ALC_DE
#include <cmath>
#include <iostream>
#include <thread>
using namespace std;
#include <AL/alut.h> // OpenAl
void 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);
}
}
#包括
#包括
#包括
使用名称空间std;
#include//OpenAl
void init_al()
{
const char*defname=alcGetString(空,ALC\u默认\u设备\u说明符);
ALCdevice*dev=alcPendDevice(defname);
ALCcontext*ctx=alcCreateContext(dev,NULL);
alcMakeContextCurrent(ctx);
}
无效退出_al()
{
ALCcontext*ctx=alcGetCurrentContext();
ALCdevice*dev=alcGetContextsDevice(ctx);
alcMakeContextCurrent(0);
alc(ctx);
自动控制装置(dev);
}
无效蜂鸣音(浮动频率=440,浮动秒数=0.5)
{
init_al();
明矾;
alGenBuffers(1,&buf);
无符号采样率=10000;
大小=秒*采样率;
短*样本=新的短[buf_大小];
如果(样本==0)
{
我在程序中添加了3行新行,并将init_al
和exit_al
放在main
中,现在问题似乎已经解决了。顺便说一句,我不知道为什么需要将init_al
和exit_al
放在main
中,所以这只是对问题的部分回答:
#include <cmath>
#include <iostream>
#include <thread>
using namespace std;
#include <AL/alut.h> // OpenAl
void 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();
}
#包括
#包括
#包括
使用名称空间std;
#include//OpenAl
void init_al()
{
const char*defname=alcGetString(空,ALC\u默认\u设备\u说明符);
ALCdevice*dev=alcPendDevice(defname);
ALCcontext*ctx=alcCreateContext(dev,NULL);
alcMakeContextCurrent(ctx);
}
无效退出_al()
{
ALCcontext*ctx=alcGetCurrentContext();
ALCdevice*dev=alcGetContextsDevice(ctx);
alcMakeContextCurrent(0);
alc(ctx);
自动控制装置(dev);
}
无效蜂鸣音(浮动频率=440,浮动秒数=0.5)
{
明矾;
alGenBuffers(1,&buf);
无符号采样率=10000;
大小=秒*采样率;
短*样本=新的短[buf_大小];
如果(样本==0)
{
当OpenAL在播放时切换上下文,或者销毁它们并关闭设备时,我认为OpenAL不会高兴。(这应该是线程函数中的delete[]samples
。)我修复了delete
。但问题仍然存在。而且我认为播放不会中断,alutSleep(秒+0.5)
防止这种情况。在此期间,您启动了多个线程,它们都会更改当前上下文。将init_al
和exit_al
从线程移动到main
(每个线程只需执行一次)。我测试过。但仍然有类似的问题发生。我认为在某个地方有漏洞。我认为你的代码中有设计缺陷。除非你为OpenAL做一些崩溃测试。你有一个声音设备和1000个用户。即使8核上有1000个线程也是相当有挑战性的。