int lua_AudioBuffer_addRef(lua_State* state)
{
    // Get the number of parameters.
    int paramCount = lua_gettop(state);

    // Attempt to match the parameters to a valid binding.
    switch (paramCount)
    {
        case 1:
        {
            if ((lua_type(state, 1) == LUA_TUSERDATA))
            {
                AudioBuffer* instance = getInstance(state);
                instance->addRef();
                
                return 0;
            }

            lua_pushstring(state, "lua_AudioBuffer_addRef - Failed to match the given parameters to a valid function signature.");
            lua_error(state);
            break;
        }
        default:
        {
            lua_pushstring(state, "Invalid number of parameters (expected 1).");
            lua_error(state);
            break;
        }
    }
    return 0;
}
Beispiel #2
0
AudioBuffer* AudioBuffer::create(const char* path)
{
    GP_ASSERT(path);

    // Search the cache for a stream from this file.
    unsigned int bufferCount = (unsigned int)__buffers.size();
    AudioBuffer* buffer = NULL;
    for (unsigned int i = 0; i < bufferCount; i++)
    {
        buffer = __buffers[i];
        GP_ASSERT(buffer);
        if (buffer->_filePath.compare(path) == 0)
        {
            buffer->addRef();
            return buffer;
        }
    }

    ALuint alBuffer;

    // Load audio data into a buffer.
    AL_CHECK( alGenBuffers(1, &alBuffer) );
    if (AL_LAST_ERROR())
    {
        GP_ERROR("Failed to create OpenAL buffer; alGenBuffers error: %d", AL_LAST_ERROR());
        AL_CHECK( alDeleteBuffers(1, &alBuffer) );
        return NULL;
    }
    
    // Load sound file.
    std::auto_ptr<Stream> stream(FileSystem::open(path));
    if (stream.get() == NULL || !stream->canRead())
    {
        GP_ERROR("Failed to load audio file %s.", path);
        goto cleanup;
    }
    
    // Read the file header
    char header[12];
    if (stream->read(header, 1, 12) != 12)
    {
        GP_ERROR("Invalid header for audio file %s.", path);
        goto cleanup;
    }
    
    // Check the file format
    if (memcmp(header, "RIFF", 4) == 0)
    {
        if (!AudioBuffer::loadWav(stream.get(), alBuffer))
        {
            GP_ERROR("Invalid wave file: %s", path);
            goto cleanup;
        }
    }
    else if (memcmp(header, "OggS", 4) == 0)
    {
        if (!AudioBuffer::loadOgg(stream.get(), alBuffer))
        {
            GP_ERROR("Invalid ogg file: %s", path);
            goto cleanup;
        }
    }
    else
    {
        GP_ERROR("Unsupported audio file: %s", path);
        goto cleanup;
    }

    buffer = new AudioBuffer(path, alBuffer);

    // Add the buffer to the cache.
    __buffers.push_back(buffer);

    return buffer;
    
cleanup:
    if (alBuffer)
        AL_CHECK( alDeleteBuffers(1, &alBuffer) );
    return NULL;
}
AudioBuffer* AudioBuffer::create(const char* path, bool streamed)
{
    GP_ASSERT(path);

    AudioBuffer* buffer = NULL;
    if (!streamed)
    {
        unsigned int bufferCount = (unsigned int)__buffers.size();
        for (unsigned int i = 0; i < bufferCount; i++)
        {
            buffer = __buffers[i];
            GP_ASSERT(buffer);
            if (buffer->_filePath.compare(path) == 0)
            {
                buffer->addRef();
                return buffer;
            }
        }
    }
    ALuint alBuffer[STREAMING_BUFFER_QUEUE_SIZE];
    memset(alBuffer, 0, sizeof(alBuffer));

    // Create 1 buffer for non-streamed sounds or full queue for streamed ones.
    unsigned int queueSize = streamed ? STREAMING_BUFFER_QUEUE_SIZE : 1;
    for (unsigned int i = 0; i < queueSize; i++)
    {
        // Load audio data into a buffer.
        AL_CHECK(alGenBuffers(1, &alBuffer[i]));
        if (AL_LAST_ERROR())
        {
            GP_ERROR("Failed to create OpenAL buffer; alGenBuffers error: %d", AL_LAST_ERROR());
            AL_CHECK(alDeleteBuffers(1, &alBuffer[i]));
            return NULL;
        }
    }
    
    std::unique_ptr<AudioStreamStateWav> streamStateWav;
    std::unique_ptr<AudioStreamStateOgg> streamStateOgg;

    // Load sound file.
    std::unique_ptr<Stream> stream(FileSystem::open(path));
    if (stream.get() == NULL || !stream->canRead())
    {
        GP_ERROR("Failed to load audio file %s.", path);
        goto cleanup;
    }
    
    // Read the file header
    char header[12];
    if (stream->read(header, 1, 12) != 12)
    {
        GP_ERROR("Invalid header for audio file %s.", path);
        goto cleanup;
    }
    
    // Check the file format
    if (memcmp(header, "RIFF", 4) == 0)
    {
        // Fill at least one buffer with sound data.
        streamStateWav.reset(new AudioStreamStateWav());
        if (!AudioBuffer::loadWav(stream.get(), alBuffer[0], streamed, streamStateWav.get()))
        {
            GP_ERROR("Invalid wave file: %s", path);
            goto cleanup;
        }
    }
    else if (memcmp(header, "OggS", 4) == 0)
    {
        // Fill at least one buffer with sound data.
        streamStateOgg.reset(new AudioStreamStateOgg());
        if (!AudioBuffer::loadOgg(stream.get(), alBuffer[0], streamed, streamStateOgg.get()))
        {
            GP_ERROR("Invalid ogg file: %s", path);
            goto cleanup;
        }
    }
    else
    {
        GP_ERROR("Unsupported audio file: %s", path);
        goto cleanup;
    }

    buffer = new AudioBuffer(path, alBuffer, streamed);

    buffer->_fileStream.reset(stream.release());
    buffer->_streamStateWav.reset(streamStateWav.release());
    buffer->_streamStateOgg.reset(streamStateOgg.release());
    if (buffer->_streamStateWav.get())
        buffer->_buffersNeededCount = (buffer->_streamStateWav->dataSize + STREAMING_BUFFER_SIZE - 1) / STREAMING_BUFFER_SIZE;
    else if (buffer->_streamStateOgg.get())
        buffer->_buffersNeededCount = (buffer->_streamStateOgg->dataSize + STREAMING_BUFFER_SIZE - 1) / STREAMING_BUFFER_SIZE;

    if (!streamed)
        __buffers.push_back(buffer);

    return buffer;
    
cleanup:
    for (unsigned int i = 0; i < STREAMING_BUFFER_QUEUE_SIZE; i++)
    {
        if (alBuffer[i])
            AL_CHECK(alDeleteBuffers(1, &alBuffer[i]));
    }
    return NULL;
}