Visual studio 2010 无法获取OpenAL以播放声音
我搜索过网,我搜索过这里。我已经找到了我可以编译的代码,它工作得很好,但由于某些原因,我的代码不会产生任何声音。我正在将一个旧游戏移植到PC Windows上,我正试图使它尽可能真实,所以我想使用生成的波形。我几乎复制并粘贴了工作代码,只添加了多个语音,即使一个语音使用完全相同的代码也可以正常工作,但仍然无法工作。我知道我遗漏了一些明显的东西,但我就是不知道是什么。任何帮助都将不胜感激,谢谢 首先是一些注释。。。我在寻找一些可以让我使用原始方法的东西。最初的系统对音乐音效使用成对字节(只有2个字节)进行编码处理。一个在每次调用例程时倒数计时的时间字节和一个一直播放到时间为零的音符字节。这是通过修补中断向量来完成的,windows不允许这样做,所以我设置了一个定时器来完成同样的事情。计时器启动,更新显示,然后运行音乐序列。我用一个定义好的时间来设置它,这样我就只有一个地方可以调整时间,使它尽可能接近原始序列。音乐是生成的波形,我仔细检查了数学,甚至在调试模式下检查了生成的数据,看起来不错。这个序列看起来不错,但实际上并不产生声音。我首先尝试了SDL2,它只播放一个声音的方法对我来说不起作用,而且,除非我使采样持续时间非常短,并且以这种方式产生的声音非常糟糕,否则我无法通过它自己的中断匹配它播放整个采样的时间,而不让我进行调整。而且,当这三种声音以不同的时间运行时,将它们混合在一起是一个混乱。我检查过的大多数其他引擎的工作方式大致相同,它们希望使用自己的回调中断,不允许我对其进行适当调整。这就是我开始与OpenAL合作的原因。它允许多种声音来源,并允许我自己设置时间。根据几个论坛的建议,我将其设置为样本长度都是完整周期的倍数。 不管怎样,这是代码Visual studio 2010 无法获取OpenAL以播放声音,visual-studio-2010,visual-c++,audio,openal,waveform,Visual Studio 2010,Visual C++,Audio,Openal,Waveform,我搜索过网,我搜索过这里。我已经找到了我可以编译的代码,它工作得很好,但由于某些原因,我的代码不会产生任何声音。我正在将一个旧游戏移植到PC Windows上,我正试图使它尽可能真实,所以我想使用生成的波形。我几乎复制并粘贴了工作代码,只添加了多个语音,即使一个语音使用完全相同的代码也可以正常工作,但仍然无法工作。我知道我遗漏了一些明显的东西,但我就是不知道是什么。任何帮助都将不胜感激,谢谢 首先是一些注释。。。我在寻找一些可以让我使用原始方法的东西。最初的系统对音乐音效使用成对字节(只有2个字
int main(int argc, char* argv[])
{
FreeConsole(); //Get rid of the DOS console, don't need it
if (InitLog() < 0) return -1; //Start logging
UINT_PTR tim = NULL;
SDL_Event event;
InitVideo(false); //Set to window for now, will put options in later
curmusic = 5;
InitAudio();
SetTimer(NULL,tim,_FREQ_,TimerProc);
SDL_PollEvent(&event);
while (event.type != SDL_KEYDOWN) SDL_PollEvent(&event);
SDL_Quit();
return 0;
}
void CALLBACK TimerProc(HWND hWind, UINT Msg, UINT_PTR idEvent, DWORD dwTime)
{
RenderOutput();
PlayMusic();
//UpdateTimer();
//RotateGate();
return;
}
void InitAudio(void)
{
ALCdevice *dev;
ALCcontext *cxt;
Log("Initializing OpenAL Audio\r\n");
dev = alcOpenDevice(NULL);
if (!dev) {
Log("Failed to open an audio device\r\n");
exit(-1);
}
cxt = alcCreateContext(dev, NULL);
alcMakeContextCurrent(cxt);
if(!cxt) {
Log("Failed to create audio context\r\n");
exit(-1);
}
alGenBuffers(4,Buffer);
if (alGetError() != AL_NO_ERROR) {
Log("Error during buffer creation\r\n");
exit(-1);
}
alGenSources(4, Source);
if (alGetError() != AL_NO_ERROR) {
Log("Error during source creation\r\n");
exit(-1);
}
return;
}
void PlayMusic()
{
static int oldsong, ofset, mtime[4];
double freq;
ALuint srate = 44100;
ALuint voice, i, note, len, hold;
short buf[4][_BUFFSIZE_];
bool test[4] = {false, false, false, false};
if (curmusic != oldsong) {
oldsong = (int)curmusic;
if (curmusic > 0)
ofset = moffset[(curmusic - 1)];
for (voice = 1; voice < 4; voice++)
alSourceStop(Source[voice]);
mtime[voice] = 0;
return;
}
if (curmusic == 0) return;
//Only 3 voices for music, but have
for (voice = 0; voice < 3; voice ++) { // 4 set asside for eventual sound effects
if (mtime[voice] == 0) { //is note finished
alSourceStop(Source[voice]); //It is, so stop the channel (source)
mtime[voice] = music[ofset++]; //Get the next duration
if (mtime[voice] == 0) {oldsong = 0; return;} //zero marks end, so restart
note = music[ofset++]; //Get the next note
if (note > 127) { //Old HW data was designed for could only
if (note == 255) note = 127; //use values 128 - 255 (255 = 127)
freq = (15980 / (voice + (int)(voice / 3))) / (256 - note); //freq of note
len = (ALuint)(srate / freq); //A single cycle of that freq.
hold = len;
while (len < (srate / (1000 / _FREQ_))) len += hold; //Multiply till 1 interrup cycle
while (len > _BUFFSIZE_) len -= hold; //Don't overload buffer
if (len == 0) len = _BUFFSIZE_; //Just to be safe
for (i = 0; i < len; i++) //calculate sine wave and put in buffer
buf[voice][i] = (short)((32760 * sin((2 * M_PI * i * freq) / srate)));
alBufferData(Buffer[voice], AL_FORMAT_MONO16, buf[voice], len, srate);
alSourcei(openAL.Source[i], AL_LOOPING, AL_TRUE);
alSourcei(Source[i], AL_BUFFER, Buffer[i]);
alSourcePlay(Source[voice]);
}
} else --mtime[voice];
}
}
我的代码有三个问题。首先,在将缓冲区链接到源之前,必须将构建的波形缓冲区链接到生成的AL缓冲区:
alBufferData(buffer,AL_FORMAT_MONO16,&wave_sample,sample_lenght * sizeof(short),frequency);
alSourcei(source,AL_BUFFER,buffer);
同样在上面的示例中,我将sample_长度乘以本例中sizeofshort中每个示例中的字节数
最后一个问题是,在更改缓冲区数据之前,需要从源中取消缓冲区链接
alSourcei(source,AL_BUFFER,NULL);
音乐会播放,但不会正确播放,直到我将这一行添加到音符更改代码。在任何人评论之前,更正被零除的问题没有帮助-最初是语音1-3,为音效预留了零。为了测试的目的,我在更改为0-3后复制了代码,但在我纠正被零除的问题之前。很抱歉将.TimerProc替换为_beginthread,因为TimerProc似乎只想在我的测试等待循环中运行,直到我按下一个键为止。它在那里工作得很好。如果我将正弦波保存到一个文件中,并用媒体播放器打开它,虽然声音不大,但听起来很好,因此我生成了正确的频率,并且我的中断时间非常接近。仍然无法使其发出声音。抱歉,将un链接代码改为NULL而不是buffer。