0

我一直有一个非常奇怪的问题,我似乎无法理解。我几乎确信这是一个编译器错误。

xTech:xIncludes.hh

#ifndef _xIncludes_
#define _xIncludes_

#define SDL_MAIN_HANDLED

#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <vector>
#include <SDL2/SDL.h>

#if defined _WIN32
    #include <winsock.h>
#endif

#endif

xTech:xSound.cc

#include "xSound.hh"

int xOGGStreamSource::_stream(ALuint Buffer) {
    char data[BufferSize];
    int size = 0;
    int section;
    int result;

    while (size < BufferSize) {
        result = ov_read(&_oggstream, data + size, BufferSize - size, 0, 2, 1, &section);

        if (result > 0)
            size += result;
        else
            if (result < 0)
                return result;
            else
                break; //This seems a little redundant.... deal with it after it works.
    }

    if (size == 0) return 0;
    alBufferData(Buffer, _format, data, size, _vorbisinfo->rate);
    return 1;
}

void xOGGStreamSource::_empty() {
    int queued;

    alGetSourcei(_source, AL_BUFFERS_QUEUED, &queued);

    while (queued--) {
        ALuint Buffer;
        alSourceUnqueueBuffers(_source, 1, &Buffer);
    }
}

int xOGGStreamSource::Open(xString path) {
    int result;

    _oggfile = xOpenFile(path, "rb");

    if (_oggfile.Buffer == NULL) {
        xLogf("Audio", "Error in OGG File '%s', file does not exist.", path);
        return -3;
    }

    if (result = ov_open(_oggfile.Buffer, &_oggstream, NULL, 0) < 0) {
        xLogf("Audio", "Error in OGG File '%s', file is non-OGG.", path);
        xCloseFile(_oggfile);
        return -2;
    }

    _vorbisinfo = ov_info(&_oggstream, -1);
    _vorbiscomment = ov_comment(&_oggstream, -1);

    if (_vorbisinfo->channels == 1)
        _format = AL_FORMAT_MONO16;
    else
        _format = AL_FORMAT_STEREO16;

    alGenBuffers(2, _buffers);
    alGenSources(1, &_source);

    return 1;
}

void xOGGStreamSource::Close() {
    alSourceStop(_source);
    _empty();
    alDeleteSources(1, &_source);
    alDeleteBuffers(1, _buffers);

    ov_clear(&_oggstream);
}

int xOGGStreamSource::Playback() {
    if (Playing()) return 1;
    if (!_stream(_buffers[0])) return 0;
    if (!_stream(_buffers[1])) return 0;

    alSourceQueueBuffers(_source, 2, _buffers);
    alSourcePlay(_source);

    return 1;
}

int xOGGStreamSource::Playing() {
    ALenum state;
    alGetSourcei(_source, AL_SOURCE_STATE, &state);
    return (state == AL_PLAYING);
}

int xOGGStreamSource::Update(xVec3f_t Pos, xVec3f_t Vloc, xVec3f_t Dir, float Vol) {
    int processed;
    int active = 1;

    alSource3f(_source, AL_POSITION,        Pos.X, Pos.Y, Pos.Z);
    alSource3f(_source, AL_VELOCITY,        Vloc.X, Vloc.Y, Vloc.Z);
    alSource3f(_source, AL_DIRECTION,       Dir.X, Dir.Y, Dir.Z);
    alSourcef (_source, AL_GAIN, Vol);
    alSourcei (_source, AL_SOURCE_RELATIVE, AL_TRUE);

    alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed);

    while(processed--) {
        ALuint Buffer;
        alSourceUnqueueBuffers(_source, 1, &Buffer);
        active = _stream(Buffer);
        alSourceQueueBuffers(_source, 1, &Buffer);
    }

    return active;
}

xSound::xSound(xOGGStreamSource xss) { _source = xss; }

int xSound::PlaySound(float Volume, xVec3f_t Location) {
    if (!_source.Playback()) return -3;

    while(_source.Update(Location, xVec3f_t(0,0,0), xVec3f_t(0,0,0), Volume)) {
        if (!_source.Playing()) {
            if (!_source.Playback()) return -2;
            else return -1;
        }
    }
    _source.Close();
    return 1;
}

xSoundManager::xSoundManager(){}

int xSoundManager::Init() {
    _device = alcOpenDevice(NULL);
    if (!_device) return -2;

    _context = alcCreateContext(_device, NULL);
    if (alcMakeContextCurrent(_context) == ALC_FALSE || !_context) return -1;

    if (!Volume) {
        xLogf("Error", "Volume in Audio is not set properly. Setting to default");
        Volume = DEFAULT_VOLUME;
    }
    alListenerf(AL_GAIN, Volume);

    if (!BufferSize) {
        xLogf("Error", "Buffer size in Audio is not set properly. Setting to default");
        BufferSize = DEFAULT_BUFFER_SIZE;
    }

    return 0;
}

xSound* xSoundManager::LoadOGG(xString file) {
    xOGGStreamSource ogg;
    if (ogg.Open(file) < 0) return NULL;

    return new xSound(ogg);
}

xTechLibTest : main.cc

int main() {
    xSetLogFile("xTechLibTest.log");

    xSoundManager* audio = new xSoundManager();
    if (audio->Init() < 0) return -1;

    xSound* testsound1 = audio->LoadOGG("testsound.ogg");
    if (testsound1 == NULL) return -2;
    testsound1->PlaySound(1.0, xVec3f_t(1.0,0.5,0.3));
}

上面的代码以及与之相关的所有内容(字符串实现等)都可以正常工作,完全没有问题。直到我包含 SDL.h;当编译器之前可以毫无问题地找到它们时,我会为我定义的每个函数获得未定义的引用。似乎仅仅包含 SDL.h 就完全否定了我所做的任何定义。有什么想法吗?

4

2 回答 2

0

您是否正确包含了与 SDL 库的链接?

如果您自己构建了二进制文件,则需要包含路径和库。在 linux 系统上,如果您自己构建了静态库,您将拥有一个名为 libSDL2.a 的二进制文件,但是要链接您需要将 SDL2 指定为链接库。

另外作为旁注,您的 xsound.h 文件(通过#ifdef _xsound_...)上是否有多余的包含保护?

ps 如果您指定环境的设置方式,它将帮助其他用户;编译器、系统操作系统、IDE。

于 2013-11-10T16:50:05.267 回答
0

查看编译器/链接器的输出会很有用。

在 Windows 机器上使用 Cygwin 时,我遇到了与网络相关的代码类似的问题。在没有 SDL 的情况下,我的套接字可以正常工作,只要我包含 SDL,整个过程就会中断,消息说找不到某些头文件和引用。

我不确定,但我认为这与 SDL 拥有自己的主要宏的方式有关(这里有一篇关于它的帖子 -包含 SDL 时简单的 tcp echo 程序不起作用?)。

我可能错了,但这与您所看到的相似吗?

于 2013-11-12T17:32:09.283 回答