关于Visual Studio 2010:无法让OpenAL播放声音

Cannot get OpenAL to play sound

我已经搜索了网络,我已经搜索了这里。我找到了可以编译的代码,并且可以正常运行,但是由于某种原因,我的代码无法发出任何声音。我正在将旧游戏移植到PC(Windows)上,并且试图使其尽可能地真实,因此我想使用生成的波形。我已经复制并粘贴了有效的代码(仅添加了多种声音),但仍然无法正常工作(甚至认为对于单个声音使用完全相同的代码也能正常工作。)我知道我丢失了显而易见的东西,但是我无法弄清楚是什么。任何帮助将不胜感激谢谢。

首先要注意的是...我正在寻找可以使我使用原始方法的东西。原始系统使用成对的字节来播放音乐(声音效果-只有2个-用代码处理)。一个时间字节在每次调用该例程时都会递减计数,而一个音符字节将一直播放到时间达到零为止。这是通过修补中断向量来完成的,Windows不允许这样做,所以我设置了一个计时器来完成相同的任务。计时器开始计时,更新显示,然后运行音乐序列。我将其设置为规定的时间,这样我就只能在一个位置调整时间(使其尽可能接近原始音序。音乐是一种产生的波形(我已经仔细检查了数学,甚至在调试模式下检查了生成的数据),它看起来不错。序列看起来不错,但实际上并没有产生声音。我首先尝试了SDL2,而它只播放1种声音的方法却没有同样,这对我也不起作用,除非我使采样持续时间非常短(并且以这种方式产生的声音很糟糕),否则我无法匹配时间(它会通过自己的中断播放整个采样而不会让我此外,将这三种声音混合在一起(当它们都以不同的时间运行时)也很混乱。我检查过的大多数其他引擎的工作方式几乎相同,他们想使用自己的回调中断并赢得\\我不允许对其进行适当的调整。这就是为什么我开始使用OpenAL的原因。它允许多种声音(来源)并允许我自己设定时间。根据几个论坛的建议,我对其进行了设置,以使样本长度全部为完整周期的倍数。
无论如何,这是代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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\
\
");
    dev = alcOpenDevice(NULL);
    if (!dev) {
        Log("Failed to open an audio device\
\
");
        exit(-1);
    }
    cxt = alcCreateContext(dev, NULL);
    alcMakeContextCurrent(cxt);
    if(!cxt) {
        Log("Failed to create audio context\
\
");
        exit(-1);
    }
    alGenBuffers(4,Buffer);
    if (alGetError() != AL_NO_ERROR) {
        Log("Error during buffer creation\
\
");
        exit(-1);
    }
    alGenSources(4, Source);
    if (alGetError() != AL_NO_ERROR) {
        Log("Error during source creation\
\
");
        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];
    }
}


好吧,事实证明我的代码有3个问题。首先,必须将内置的wave缓冲区链接到AL生成的缓冲区" before ",然后将缓冲区链接到源:

1
2
alBufferData(buffer,AL_FORMAT_MONO16,&wave_sample,sample_lenght * sizeof(short),frequency);
alSourcei(source,AL_BUFFER,buffer);

同样在上面的示例中,我将sample_length乘以每个样本中的字节数(在本例中为" sizeof(short)"。

最后的问题是,在更改缓冲区数据之前,需要先断开缓冲区与源的链接

1
alSourcei(source,AL_BUFFER,NULL);

音乐会播放,但是要正确播放,直到我将该行添加到音符更改代码中为止。