Ejemplo n.º 1
0
void AudioSource::setLooped(bool looped)
{
    AL_CHECK( alSourcei(_alSource, AL_LOOPING, (looped) ? AL_TRUE : AL_FALSE) );
    if (AL_LAST_ERROR())
    {
        GP_ERROR("Failed to set audio source's looped attribute with error: %d", AL_LAST_ERROR());
    }
    _looped = looped;
}
Ejemplo n.º 2
0
AudioSource* AudioSource::clone(NodeCloneContext &context) const
{
    GP_ASSERT(_buffer);

    ALuint alSource = 0;
    AL_CHECK( alGenSources(1, &alSource) );
    if (AL_LAST_ERROR())
    {
        GP_ERROR("Error generating audio source.");
        return NULL;
    }
    AudioSource* audioClone = new AudioSource(_buffer, alSource);

    _buffer->addRef();
    audioClone->setLooped(isLooped());
    audioClone->setGain(getGain());
    audioClone->setPitch(getPitch());
    audioClone->setVelocity(getVelocity());
    if (Node* node = getNode())
    {
        Node* clonedNode = context.findClonedNode(node);
        if (clonedNode)
        {
            audioClone->setNode(clonedNode);
        }
    }
    return audioClone;
}
Ejemplo n.º 3
0
AudioSource* AudioSource::create(const char* url)
{
    // Load from a .audio file.
    std::string pathStr = url;
    if (pathStr.find(".audio") != std::string::npos)
    {
        Properties* properties = Properties::create(url);
        if (properties == NULL)
        {
            GP_ERROR("Failed to create audio source from .audio file.");
            return NULL;
        }

        AudioSource* audioSource = create((strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace());
        SAFE_DELETE(properties);
        return audioSource;
    }

    // Create an audio buffer from this URL.
    AudioBuffer* buffer = AudioBuffer::create(url);
    if (buffer == NULL)
        return NULL;

    // Load the audio source.
    ALuint alSource = 0;

    AL_CHECK( alGenSources(1, &alSource) );
    if (AL_LAST_ERROR())
    {
        SAFE_RELEASE(buffer);
        GP_ERROR("Error generating audio source.");
        return NULL;
    }
    
    return new AudioSource(buffer, alSource);
}
Ejemplo n.º 4
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;
}