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; }
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; }