В этой программе функция alDeleteBuffers
производит Invalid Name
ошибка через несколько секунд:
#include <stdio.h>
#include <math.h>#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#elif __linux
#include <AL/al.h>
#include <AL/alut.h>
#include <AL/alc.h>
#endif#include <iostream>
#include <thread>
using namespace std;class Sound
{
public:
ALCdevice* openal_output_device;
ALCcontext* openal_output_context;int al_check_error(const char * given_label)
{
ALenum al_error = alGetError();
if(al_error != AL_NO_ERROR)
{
printf("ERROR - %s (%s)\n", alGetString(al_error), given_label);
return al_error;
}
return 0;
}
void StartAl()
{
const char* defname = alcGetString(0,ALC_DEFAULT_DEVICE_SPECIFIER);
openal_output_device = alcOpenDevice(defname);
openal_output_context = alcCreateContext(openal_output_device,0);
alcMakeContextCurrent(openal_output_context);
}
void EndAl()
{
alcMakeContextCurrent(0);
al_check_error("EndAl1");
alcDestroyContext(openal_output_context);
al_check_error("EndAl2");
alcCloseDevice(openal_output_device);
al_check_error("EndAl3");
}
void Beep(float frequency, float seconds)
{
seconds *= 2;
ALuint internal_buffer;
ALuint streaming_source[1];
alGenBuffers(1,&internal_buffer);
al_check_error("failed call to alGenBuffers");
/* Fill buffer with Sine-Wave */
unsigned sample_rate = 10000;
size_t buf_size = seconds*sample_rate;
// allocate PCM audio buffer
short* samples = new short[buf_size];
for(int i = 0; i < buf_size; i++)
samples[i] = 32760*sin(2*M_PI*i*frequency/sample_rate);/* upload buffer to OpenAL */
alBufferData(internal_buffer, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
al_check_error("alBufferData Failed");
delete[] samples;//free(samples);
/* Set-up sound source and play buffer */
alGenSources(1,&streaming_source[0]);
alSourcei(streaming_source[0], AL_BUFFER, internal_buffer);
alSourcePlay(streaming_source[0]);ALenum current_playing_state;
alGetSourcei(streaming_source[0],AL_SOURCE_STATE,¤t_playing_state);
al_check_error("alGetSourcei Failed");
alutSleep(seconds);
while(current_playing_state == AL_PLAYING)
{
alGetSourcei(streaming_source[0], AL_SOURCE_STATE, ¤t_playing_state);
if(al_check_error("alGetSourcei in while loop") != 0)
break;
alutSleep(0.1);
}
alSourceStopv(1,&streaming_source[0]);
al_check_error("alSourceStopv");
alSourcei(streaming_source[0],AL_BUFFER,0);
al_check_error("alSourcei");
alDeleteSources(1,&streaming_source[0]);
al_check_error("alDeleteSources");
alDeleteBuffers(16,&streaming_source[0]); // HERE HERE HERE HERE
al_check_error("alDeleteBuffers");
}
Sound()
{
StartAl();
}
~Sound()
{
EndAl();
}
};void Beep(float frequency = 440, float seconds = 1)
{
static Sound s;
s.Beep(frequency,seconds);
}int main()
{
for(int i = 0; i < 1000; i++)
{
thread t(Beep, 840,0.5);
t.detach();
alutSleep(0.01);
cout<< i << "\n";
}
cin.get();
}
Также все функции OpenAl в EndAl
метод производства (null)
ошибка.
Почему это происходит и есть ли способ это исправить?
Линия
alDeleteBuffers(16,&streaming_source[0]);
Нужно ли освободить буферы и память забрать?
Я предлагаю вам изменить
alDeleteBuffers(16,&streaming_source[0]); // HERE HERE HERE HERE
в
alDeleteBuffers(1,&internal_buffer); // HERE HERE HERE HERE
Потому что эта функция, похоже, удаляет буфер.
Также вам не нужно использовать массив:
ALuint streaming_source[1];
Вместо этого используйте переменную, чтобы получить более простой код.
Около (null)
ошибка, у меня нет идей, вероятно, это не ошибка, потому что OpenAl закончен и, вероятно, alGetError
не будет использоваться в такой ситуации.