C++ 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

我试着用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_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个线程也是相当有挑战性的。