VkPipelineLayout VulkanDescriptorManager::getPipelineLayout(VulkanDescriptorLayout** layouts, UINT32 numLayouts) { VulkanPipelineLayoutKey key(layouts, numLayouts); auto iterFind = mPipelineLayouts.find(key); if (iterFind != mPipelineLayouts.end()) return iterFind->second; // Create new VkDescriptorSetLayout* setLayouts = (VkDescriptorSetLayout*)bs_stack_alloc(sizeof(VkDescriptorSetLayout) * numLayouts); for(UINT32 i = 0; i < numLayouts; i++) setLayouts[i] = layouts[i]->getHandle(); VkPipelineLayoutCreateInfo layoutCI; layoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutCI.pNext = nullptr; layoutCI.flags = 0; layoutCI.pushConstantRangeCount = 0; layoutCI.pPushConstantRanges = nullptr; layoutCI.setLayoutCount = numLayouts; layoutCI.pSetLayouts = setLayouts; VkPipelineLayout pipelineLayout; VkResult result = vkCreatePipelineLayout(mDevice.getLogical(), &layoutCI, gVulkanAllocator, &pipelineLayout); assert(result == VK_SUCCESS); bs_stack_free(setLayouts); key.layouts = (VulkanDescriptorLayout**)bs_alloc(sizeof(VulkanDescriptorLayout*) * numLayouts); memcpy(key.layouts, layouts, sizeof(VulkanDescriptorLayout*) * numLayouts); mPipelineLayouts.insert(std::make_pair(key, pipelineLayout)); return pipelineLayout; }
bitstring* sdm_thread_read(struct sdm_memory* sdm, bitstring* address) { pthread_t thread[sdm_thread_count]; sdm_thread_params params[sdm_thread_count]; int32_t adder[sdm_thread_count][bs_dimension]; int32_t adder2[bs_dimension]; adder_t adder3[bs_dimension]; unsigned int i, j; for(i=0; i<sdm_thread_count; i++) { params[i].id = i; params[i].sdm = sdm; params[i].address = address; params[i].adder = adder[i]; pthread_create(&thread[i], NULL, sdm_thread_read_task, (void*) ¶ms[i]); } for(i=0; i<sdm_thread_count; i++) { pthread_join(thread[i], NULL); } // clear accumulator for(j=0; j<bs_dimension; j++) adder2[j] = 0; // accumulate for(i=0; i<sdm_thread_count; i++) { for(j=0; j<bs_dimension; j++) { adder2[j] += adder[i][j]; } } // we can't add all adders in an adder_t type because // it will probably overflow. for(j=0; j<bs_dimension; j++) { if (adder2[j] > 0) adder3[j] = 1; else if (adder2[j] < 0) adder3[j] = -1; else adder3[j] = (rand()%2 == 0 ? 1 : -1); } //printf("Hardlocation inside radius %d = %d\n", sdm_radius, counter); return bs_init_adder(bs_alloc(), adder3); }
/** Gets a file list from data. Caller must ensure that the data actually contains a file list. */ Vector<Path>* Win32DropTarget::getFileListFromData(IDataObject* data) { FORMATETC fmtetc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stgmed; Vector<Path>* files = bs_new<Vector<Path>>(); if(data->GetData(&fmtetc, &stgmed) == S_OK) { PVOID data = GlobalLock(stgmed.hGlobal); HDROP hDrop = (HDROP)data; UINT numFiles = DragQueryFileW(hDrop, 0xFFFFFFFF, nullptr, 0); files->resize(numFiles); for(UINT i = 0; i < numFiles; i++) { UINT numChars = DragQueryFileW(hDrop, i, nullptr, 0) + 1; wchar_t* buffer = (wchar_t*)bs_alloc((UINT32)numChars * sizeof(wchar_t)); DragQueryFileW(hDrop, i, buffer, numChars); (*files)[i] = UTF8::fromWide(WString(buffer)); bs_free(buffer); } GlobalUnlock(stgmed.hGlobal); ReleaseStgMedium(&stgmed); } return files; }
bool checkForGLSLError(const GLuint programObj, String& outErrorMsg) { StringStream stream; GLint linkCompileSuccess = 0; glGetProgramiv(programObj, GL_LINK_STATUS, &linkCompileSuccess); BS_CHECK_GL_ERROR(); if (!linkCompileSuccess && programObj > 0) { GLint infologLength = 0; glGetProgramiv(programObj, GL_INFO_LOG_LENGTH, &infologLength); BS_CHECK_GL_ERROR(); if (infologLength > 0) { GLint charsWritten = 0; GLchar* infoLog = (GLchar*)bs_alloc(sizeof(GLchar)* infologLength); glGetProgramInfoLog(programObj, infologLength, &charsWritten, infoLog); BS_CHECK_GL_ERROR(); stream << "Compile and linker info log: \n"; stream << String(infoLog); bs_free(infoLog); } } outErrorMsg = stream.str(); return !linkCompileSuccess; }
void MonoMethod::cacheSignature() const { MonoMethodSignature* methodSignature = mono_method_signature(mMethod); MonoType* returnType = mono_signature_get_return_type(methodSignature); if (returnType != nullptr) { ::MonoClass* returnClass = mono_class_from_mono_type(returnType); if (returnClass != nullptr) mCachedReturnType = MonoManager::instance().findClass(returnClass); } mCachedNumParameters = (UINT32)mono_signature_get_param_count(methodSignature); if (mCachedParameters != nullptr) { bs_free(mCachedParameters); mCachedParameters = nullptr; } if (mCachedNumParameters > 0) { mCachedParameters = (MonoClass**)bs_alloc(mCachedNumParameters * sizeof(MonoClass*)); void* iter = nullptr; for (UINT32 i = 0; i < mCachedNumParameters; i++) { MonoType* curParamType = mono_signature_get_params(methodSignature, &iter); ::MonoClass* rawClass = mono_class_from_mono_type(curParamType); mCachedParameters[i] = MonoManager::instance().findClass(rawClass); } } mIsStatic = !mono_signature_is_instance(methodSignature); mHasCachedSignature = true; }
hardlocation* hl_alloc() { hardlocation* hl = (hardlocation*) malloc(sizeof(hardlocation)); assert(hl != NULL); hl->address = bs_alloc(); hl->adder = (typeof(hl->adder)) malloc(sizeof(hl->adder[0])*bs_dimension); assert(hl->adder != NULL); return hl; }
GpuParamBlockBuffer::GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage, GpuDeviceFlags deviceMask) :mUsage(usage), mSize(size), mCachedData(nullptr), mGPUBufferDirty(false) { if (mSize > 0) { mCachedData = (UINT8*)bs_alloc(mSize); memset(mCachedData, 0, mSize); } }
GpuParamBlockBuffer::GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage) :mUsage(usage), mSize(size), mCachedData(nullptr) { if (mSize > 0) { mCachedData = (UINT8*)bs_alloc(mSize); memset(mCachedData, 0, mSize); } }
String D3D11Driver::getDriverName() const { size_t size = wcslen(mAdapterIdentifier.Description); char* str = (char*)bs_alloc((UINT32)(size + 1)); wcstombs(str, mAdapterIdentifier.Description, size); str[size] = '\0'; String Description = str; bs_free(str); return String(Description ); }
StringID::InitStatics::InitStatics() { ScopedSpinLock lock(mSync); memset(mStringHashTable, 0, sizeof(mStringHashTable)); memset(mChunks, 0, sizeof(mChunks)); mChunks[0] = (InternalData*)bs_alloc(sizeof(InternalData) * ELEMENTS_PER_CHUNK); memset(mChunks[0], 0, sizeof(InternalData) * ELEMENTS_PER_CHUNK); mNumChunks++; }
/*---- bitstream writer ----*/ void lsmash_bs_put_byte( lsmash_bs_t *bs, uint8_t value ) { if( bs->buffer.internal || bs->buffer.data ) { bs_alloc( bs, bs->buffer.store + 1 ); if( bs->error ) return; bs->buffer.data[ bs->buffer.store ] = value; } ++ bs->buffer.store; }
void lsmash_bs_put_bytes( lsmash_bs_t *bs, uint32_t size, void *value ) { if( size == 0 || !value ) return; if( bs->buffer.internal || bs->buffer.data ) { bs_alloc( bs, bs->buffer.store + size ); if( bs->error ) return; memcpy( lsmash_bs_get_buffer_data_end( bs ), value, size ); } bs->buffer.store += size; }
int main() { bs_ptr bsptr; if (!(bsptr = bs_alloc(75))) { printf("Failed to create bitvector\n"); } printf("Setting bits 0, 10, 21, 33, 50, 74\n"); set_bit(bsptr, 0); set_bit(bsptr, 10); set_bit(bsptr, 21); set_bit(bsptr, 33); set_bit(bsptr, 50); set_bit(bsptr, 74); printf("Checking Values of bits 0, 10, 21, 33, 50, 74\n"); printf("Value of bit 0: %d\n", get_bit(bsptr, 0)); printf("Value of bit 10: %d\n", get_bit(bsptr, 10)); printf("Value of bit 21: %d\n", get_bit(bsptr, 21)); printf("Value of bit 33: %d\n", get_bit(bsptr, 33)); printf("Value of bit 50: %d\n", get_bit(bsptr, 50)); printf("Value of bit 74: %d\n", get_bit(bsptr, 74)); printf("Checking Values of bits 1, 11, 22, 34, 51, 73\n"); printf("Value of bit 1: %d\n", get_bit(bsptr, 1)); printf("Value of bit 11: %d\n", get_bit(bsptr, 11)); printf("Value of bit 22: %d\n", get_bit(bsptr, 22)); printf("Value of bit 34: %d\n", get_bit(bsptr, 34)); printf("Value of bit 51: %d\n", get_bit(bsptr, 51)); printf("Value of bit 73: %d\n", get_bit(bsptr, 73)); printf("Clearing bits 0, 21, 50\n"); clr_bit(bsptr, 0); clr_bit(bsptr, 21); clr_bit(bsptr, 50); printf("Checking Values of bits 0, 10, 21, 33, 50, 74\n"); printf("Value of bit 0: %d\n", get_bit(bsptr, 0)); printf("Value of bit 10: %d\n", get_bit(bsptr, 10)); printf("Value of bit 21: %d\n", get_bit(bsptr, 21)); printf("Value of bit 33: %d\n", get_bit(bsptr, 33)); printf("Value of bit 50: %d\n", get_bit(bsptr, 50)); printf("Value of bit 74: %d\n", get_bit(bsptr, 74)); }
FileEncoder::FileEncoder(const Path& fileLocation) :mWriteBuffer(nullptr) { mWriteBuffer = (UINT8*)bs_alloc(WRITE_BUFFER_SIZE); Path parentDir = fileLocation.getDirectory(); if (!FileSystem::exists(parentDir)) FileSystem::createDir(parentDir); mOutputStream.open(fileLocation.toPlatformString().c_str(), std::ios::out | std::ios::binary); if (mOutputStream.fail()) { LOGWRN("Failed to save file: \"" + fileLocation.toString() + "\". Error: " + strerror(errno) + "."); } }
hardlocation* hl_alloc() { hardlocation* hl = (hardlocation*) malloc(sizeof(hardlocation)); assert(hl != NULL); hl->address = bs_alloc(); hl->adder = (typeof(hl->adder)) malloc(sizeof(hl->adder[0])*bs_dimension); assert(hl->adder != NULL); //LINHARES START //hl->num_items = malloc(sizeof(int)); hl->num_items = 0; float N = (float) bs_dimension; //hl->p = malloc(sizeof(float)); hl->p = (N-451.0)/N; //LINHARES END return hl; }
void resizeFaceArray(UINT32 numFaces) { UINT32* newFaces = (UINT32*)bs_alloc(numFaces * mNumVertices * sizeof(UINT32)); if (mFaces != nullptr) { for (UINT32 i = 0; i < mNumVertices; i++) memcpy(newFaces + (i * numFaces), mFaces + (i * mMaxFacesPerVertex), mMaxFacesPerVertex * sizeof(UINT32)); bs_free(mFaces); } for (UINT32 i = 0; i < mNumVertices; i++) vertexFaces[i].faces = newFaces + (i * numFaces); mFaces = newFaces; mMaxFacesPerVertex = numFaces; }
static FileAction* createModified(const String& fileName) { UINT8* bytes = (UINT8*)bs_alloc((UINT32)(sizeof(FileAction) + (fileName.size() + 1) * sizeof(String::value_type))); FileAction* action = (FileAction*)bytes; bytes += sizeof(FileAction); action->oldName = nullptr; action->newName = (String::value_type*)bytes; action->type = FileActionType::Modified; memcpy(action->newName, fileName.data(), fileName.size() * sizeof(String::value_type)); action->newName[fileName.size()] = L'\0'; action->lastSize = 0; action->checkForWriteStarted = false; return action; }
UINT8* OggVorbisEncoder::PCMToOggVorbis(UINT8* samples, const AudioDataInfo& info, UINT32& size) { struct EncodedBlock { UINT8* data; UINT32 size; }; Vector<EncodedBlock> blocks; UINT32 totalEncodedSize = 0; auto writeCallback = [&](UINT8* buffer, UINT32 size) { EncodedBlock newBlock; newBlock.data = bs_frame_alloc(size); newBlock.size = size; memcpy(newBlock.data, buffer, size); blocks.push_back(newBlock); totalEncodedSize += size; }; bs_frame_mark(); OggVorbisEncoder writer; writer.open(writeCallback, info.sampleRate, info.bitDepth, info.numChannels); writer.write(samples, info.numSamples); writer.close(); UINT8* outSampleBuffer = (UINT8*)bs_alloc(totalEncodedSize); UINT32 offset = 0; for (auto& block : blocks) { memcpy(outSampleBuffer + offset, block.data, block.size); offset += block.size; bs_frame_free(block.data); } bs_frame_clear(); size = totalEncodedSize; return outSampleBuffer; }
StringID::InternalData* StringID::allocEntry() { UINT32 chunkIdx = mNextId / ELEMENTS_PER_CHUNK; assert(chunkIdx < MAX_CHUNK_COUNT); assert(chunkIdx <= mNumChunks); // Can only increment sequentially if (chunkIdx >= mNumChunks) { mChunks[chunkIdx] = (InternalData*)bs_alloc(sizeof(InternalData) * ELEMENTS_PER_CHUNK); memset(mChunks[chunkIdx], 0, sizeof(InternalData) * ELEMENTS_PER_CHUNK); mNumChunks++; } InternalData* chunk = mChunks[chunkIdx]; UINT32 chunkSpecificIndex = mNextId % ELEMENTS_PER_CHUNK; InternalData* newEntry = &chunk[chunkSpecificIndex]; newEntry->id = mNextId++; newEntry->next = nullptr; return newEntry; }
SPtr<Resource> FMODImporter::import(const Path& filePath, SPtr<const ImportOptions> importOptions) { WString extension = filePath.getWExtension(); StringUtil::toLowerCase(extension); AudioFileInfo info; FMOD::Sound* sound; String pathStr = filePath.toString(); if(gFMODAudio()._getFMOD()->createSound(pathStr.c_str(), FMOD_CREATESAMPLE, nullptr, &sound) != FMOD_OK) { LOGERR("Failed importing audio file: " + pathStr); return nullptr; } FMOD_SOUND_FORMAT format; INT32 numChannels = 0; INT32 numBits = 0; sound->getFormat(nullptr, &format, &numChannels, &numBits); if(format != FMOD_SOUND_FORMAT_PCM8 && format != FMOD_SOUND_FORMAT_PCM16 && format != FMOD_SOUND_FORMAT_PCM24 && format != FMOD_SOUND_FORMAT_PCM32 && format != FMOD_SOUND_FORMAT_PCMFLOAT) { LOGERR("Failed importing audio file, invalid imported format: " + pathStr); return nullptr; } float frequency = 0.0f; sound->getDefaults(&frequency, nullptr); UINT32 size; sound->getLength(&size, FMOD_TIMEUNIT_PCMBYTES); info.bitDepth = numBits; info.numChannels = numChannels; info.sampleRate = (UINT32)frequency; info.numSamples = size / (info.bitDepth / 8); UINT32 bytesPerSample = info.bitDepth / 8; UINT32 bufferSize = info.numSamples * bytesPerSample; UINT8* sampleBuffer = (UINT8*)bs_alloc(bufferSize); assert(bufferSize == size); UINT8* startData = nullptr; UINT8* endData = nullptr; UINT32 startSize = 0; UINT32 endSize = 0; sound->lock(0, size, (void**)&startData, (void**)&endData, &startSize, &endSize); if(format == FMOD_SOUND_FORMAT_PCMFLOAT) { assert(info.bitDepth == 32); UINT32* output = (UINT32*)sampleBuffer; for(UINT32 i = 0; i < info.numSamples; i++) { float value = *(((float*)startData) + i); *output = (UINT32)(value * 2147483647.0f); output++; } } else { memcpy(sampleBuffer, startData, bufferSize); } sound->unlock((void**)&startData, (void**)&endData, startSize, endSize); sound->release(); SPtr<const AudioClipImportOptions> clipIO = std::static_pointer_cast<const AudioClipImportOptions>(importOptions); // If 3D, convert to mono if (clipIO->getIs3D() && info.numChannels > 1) { UINT32 numSamplesPerChannel = info.numSamples / info.numChannels; UINT32 monoBufferSize = numSamplesPerChannel * bytesPerSample; UINT8* monoBuffer = (UINT8*)bs_alloc(monoBufferSize); AudioUtility::convertToMono(sampleBuffer, monoBuffer, info.bitDepth, numSamplesPerChannel, info.numChannels); info.numSamples = numSamplesPerChannel; info.numChannels = 1; bs_free(sampleBuffer); sampleBuffer = monoBuffer; bufferSize = monoBufferSize; } // Convert bit depth if needed if (clipIO->getBitDepth() != info.bitDepth) { UINT32 outBufferSize = info.numSamples * (clipIO->getBitDepth() / 8); UINT8* outBuffer = (UINT8*)bs_alloc(outBufferSize); AudioUtility::convertBitDepth(sampleBuffer, info.bitDepth, outBuffer, clipIO->getBitDepth(), info.numSamples); info.bitDepth = clipIO->getBitDepth(); bs_free(sampleBuffer); sampleBuffer = outBuffer; bufferSize = outBufferSize; } // Encode to Ogg Vorbis if needed if (clipIO->getFormat() == AudioFormat::VORBIS) { // TODO - Encode to Ogg Vorbis! } SPtr<MemoryDataStream> sampleStream = bs_shared_ptr_new<MemoryDataStream>(sampleBuffer, bufferSize); AUDIO_CLIP_DESC clipDesc; clipDesc.bitDepth = info.bitDepth; clipDesc.format = clipIO->getFormat(); clipDesc.frequency = info.sampleRate; clipDesc.numChannels = info.numChannels; clipDesc.readMode = clipIO->getReadMode(); clipDesc.is3D = clipIO->getIs3D(); SPtr<AudioClip> clip = AudioClip::_createPtr(sampleStream, bufferSize, info.numSamples, clipDesc); WString fileName = filePath.getWFilename(false); clip->setName(fileName); return clip; }
/** * Attempts to cook a convex mesh from the provided mesh data. Assumes the mesh data is not null and contains vertex * positions as well as face indices. If the method returns true the resulting convex mesh will be output in the @p * data buffer, and its size in @p size. The data buffer will be allocated used the generic allocator and is up to the * caller to free it. */ bool cookConvex(PxCooking* cooking, const SPtr<MeshData>& meshData, UINT8** data, UINT32& size) { SPtr<VertexDataDesc> vertexDesc = meshData->getVertexDesc(); // Try to create hull from points PxConvexMeshDesc convexDesc; convexDesc.points.count = meshData->getNumVertices(); convexDesc.points.stride = vertexDesc->getVertexStride(); convexDesc.points.data = meshData->getElementData(VES_POSITION); convexDesc.flags |= PxConvexFlag::eCOMPUTE_CONVEX; PxDefaultMemoryOutputStream output; if (cooking->cookConvexMesh(convexDesc, output)) { size = output.getSize(); *data = (UINT8*)bs_alloc(size); memcpy(*data, output.getData(), size); return true; } // Try inflating the convex mesh convexDesc.flags |= PxConvexFlag::eINFLATE_CONVEX; if (cooking->cookConvexMesh(convexDesc, output)) { size = output.getSize(); *data = (UINT8*)bs_alloc(size); memcpy(*data, output.getData(), size); return true; } // Nothing works, just compute an AABB AABox box; auto vertIter = meshData->getVec3DataIter(VES_POSITION); do { box.merge(vertIter.getValue()); } while (vertIter.moveNext()); Vector3 aabbVerts[8]; aabbVerts[0] = box.getCorner(AABox::FAR_LEFT_BOTTOM); aabbVerts[1] = box.getCorner(AABox::FAR_RIGHT_BOTTOM); aabbVerts[2] = box.getCorner(AABox::FAR_RIGHT_TOP); aabbVerts[3] = box.getCorner(AABox::FAR_LEFT_TOP); aabbVerts[4] = box.getCorner(AABox::NEAR_LEFT_BOTTOM); aabbVerts[5] = box.getCorner(AABox::NEAR_RIGHT_BOTTOM); aabbVerts[6] = box.getCorner(AABox::NEAR_RIGHT_TOP); aabbVerts[7] = box.getCorner(AABox::NEAR_LEFT_TOP); convexDesc.points.count = 8; convexDesc.points.stride = sizeof(Vector3); convexDesc.points.data = &aabbVerts[0]; convexDesc.flags &= ~PxConvexFlag::eINFLATE_CONVEX; if (cooking->cookConvexMesh(convexDesc, output)) { size = output.getSize(); *data = (UINT8*)bs_alloc(size); memcpy(*data, output.getData(), size); return true; } return false; }
/** * Attempts to cook a triangle or convex mesh from the provided mesh data. Will log a warning and return false if it is * unable to cook the mesh. If the method returns true the resulting convex mesh will be output in the @p data buffer, * and its size in @p size. The data buffer will be allocated used the generic allocator and is up to the caller to * free it. */ bool cookMesh(const SPtr<MeshData>& meshData, PhysicsMeshType type, UINT8** data, UINT32& size) { if (meshData == nullptr) return false; PxCooking* cooking = gPhysX().getCooking(); if (cooking == nullptr) { LOGWRN("Attempting to cook a physics mesh but cooking is not enabled globally."); return false; } SPtr<VertexDataDesc> vertexDesc = meshData->getVertexDesc(); if (!vertexDesc->hasElement(VES_POSITION)) { LOGWRN("Provided PhysicsMesh mesh data has no vertex positions."); return false; } if (type == PhysicsMeshType::Convex) { if(!cookConvex(cooking, meshData, data, size)) { LOGWRN("Failed cooking a convex mesh. Perpahs it is too complex? Maximum number of convex vertices is 256."); return false; } } else { PxTriangleMeshDesc meshDesc; meshDesc.points.count = meshData->getNumVertices(); meshDesc.points.stride = vertexDesc->getVertexStride(); meshDesc.points.data = meshData->getElementData(VES_POSITION); meshDesc.triangles.count = meshData->getNumIndices() / 3; meshDesc.flags |= PxMeshFlag::eFLIPNORMALS; IndexType indexType = meshData->getIndexType(); if (indexType == IT_32BIT) { meshDesc.triangles.stride = 3 * sizeof(PxU32); meshDesc.triangles.data = meshData->getIndices32(); } else { meshDesc.triangles.stride = 3 * sizeof(PxU16); meshDesc.triangles.data = meshData->getIndices16(); meshDesc.flags |= PxMeshFlag::e16_BIT_INDICES; } PxDefaultMemoryOutputStream output; if (!cooking->cookTriangleMesh(meshDesc, output)) return false; size = output.getSize(); *data = (UINT8*)bs_alloc(size); memcpy(*data, output.getData(), size); } return true; }
void FMODAudioClip::initialize() { AudioFileInfo info; info.bitDepth = mDesc.bitDepth; info.numChannels = mDesc.numChannels; info.numSamples = mNumSamples; info.sampleRate = mDesc.frequency; // If we need to keep source data, read everything into memory and keep a copy if (mKeepSourceData) { mStreamData->seek(mStreamOffset); UINT8* sampleBuffer = (UINT8*)bs_alloc(mStreamSize); mStreamData->read(sampleBuffer, mStreamSize); mSourceStreamData = bs_shared_ptr_new<MemoryDataStream>(sampleBuffer, mStreamSize); mSourceStreamSize = mStreamSize; } FMOD::System* fmod = gFMODAudio()._getFMOD(); FMOD_MODE flags = FMOD_OPENMEMORY; if (is3D()) flags |= FMOD_3D; else flags |= FMOD_2D; // Load data into a sound buffer // TODO - Vorbis cannot be decompressed from memory by FMOD. Instead we force AudioReadMode::Stream for it. if(mDesc.readMode == AudioReadMode::LoadDecompressed || (mDesc.readMode == AudioReadMode::LoadCompressed && mDesc.format != AudioFormat::VORBIS)) { // Read all data into memory SPtr<DataStream> stream; UINT32 offset = 0; if (mSourceStreamData != nullptr) // If it's already loaded in memory, use it directly stream = mSourceStreamData; else { stream = mStreamData; offset = mStreamOffset; } UINT32 bufferSize = info.numSamples * (info.bitDepth / 8); UINT8* sampleBuffer = (UINT8*)bs_stack_alloc(bufferSize); stream->seek(offset); stream->read(sampleBuffer, bufferSize); FMOD_CREATESOUNDEXINFO exInfo; memset(&exInfo, 0, sizeof(exInfo)); exInfo.cbsize = sizeof(exInfo); exInfo.length = bufferSize; bool loadCompressed = mDesc.readMode == AudioReadMode::LoadCompressed && mDesc.format != AudioFormat::PCM; if (loadCompressed) flags |= FMOD_CREATECOMPRESSEDSAMPLE; else flags |= FMOD_CREATESAMPLE; if(fmod->createSound((const char*)sampleBuffer, flags, &exInfo, &mSound) != FMOD_OK) { LOGERR("Failed playing sound."); } else { mSound->setMode(FMOD_LOOP_OFF); } mStreamData = nullptr; mStreamOffset = 0; mStreamSize = 0; bs_stack_free(sampleBuffer); } else // Streaming { // Do nothing, we rely on AudioSource from creating sounds as only one streaming sound can ever be playing } AudioClip::initialize(); }
void MonoAssembly::load(MonoDomain* domain) { if (mIsLoaded) unload(); // Load assembly from memory because mono_domain_assembly_open keeps a lock on the file SPtr<DataStream> assemblyStream = FileSystem::openFile(mPath, true); if (assemblyStream == nullptr) { LOGERR("Cannot load assembly at path \"" + toString(mPath) + "\" because the file doesn't exist"); return; } UINT32 assemblySize = (UINT32)assemblyStream->size(); char* assemblyData = (char*)bs_stack_alloc(assemblySize); assemblyStream->read(assemblyData, assemblySize); String imageName = Path(mPath).getFilename(); MonoImageOpenStatus status = MONO_IMAGE_OK; MonoImage* image = mono_image_open_from_data_with_name(assemblyData, assemblySize, true, &status, false, imageName.c_str()); bs_stack_free(assemblyData); if (status != MONO_IMAGE_OK || image == nullptr) { LOGERR("Failed loading image data for assembly \"" + toString(mPath) + "\""); return; } // Load MDB file #if BS_DEBUG_MODE Path mdbPath = mPath + L".mdb"; if (FileSystem::exists(mdbPath)) { SPtr<DataStream> mdbStream = FileSystem::openFile(mdbPath, true); if (mdbStream != nullptr) { UINT32 mdbSize = (UINT32)mdbStream->size(); mDebugData = (UINT8*)bs_alloc(mdbSize); mdbStream->read(mDebugData, mdbSize); mono_debug_open_image_from_memory(image, mDebugData, mdbSize); } } #endif mMonoAssembly = mono_assembly_load_from_full(image, imageName.c_str(), &status, false); if (status != MONO_IMAGE_OK || mMonoAssembly == nullptr) { LOGERR("Failed loading assembly \"" + toString(mPath) + "\""); return; } mMonoImage = image; if(mMonoImage == nullptr) { BS_EXCEPT(InvalidParametersException, "Cannot get script assembly image."); } mIsLoaded = true; mIsDependency = false; }
bitstring* hl_read(hardlocation* hl) { return bs_init_adder(bs_alloc(), hl->adder); }
void OAAudioClip::initialize() { { Lock lock(mMutex); // Needs to be called even if stream data is null, to ensure memory fence is added so the // other thread sees properly initialized AudioClip members AudioDataInfo info; info.bitDepth = mDesc.bitDepth; info.numChannels = mDesc.numChannels; info.numSamples = mNumSamples; info.sampleRate = mDesc.frequency; // If we need to keep source data, read everything into memory and keep a copy if (mKeepSourceData) { mStreamData->seek(mStreamOffset); UINT8* sampleBuffer = (UINT8*)bs_alloc(mStreamSize); mStreamData->read(sampleBuffer, mStreamSize); mSourceStreamData = bs_shared_ptr_new<MemoryDataStream>(sampleBuffer, mStreamSize); mSourceStreamSize = mStreamSize; } // Load decompressed data into a sound buffer bool loadDecompressed = mDesc.readMode == AudioReadMode::LoadDecompressed || (mDesc.readMode == AudioReadMode::LoadCompressed && mDesc.format == AudioFormat::PCM); if(loadDecompressed) { // Read all data into memory SPtr<DataStream> stream; UINT32 offset = 0; if (mSourceStreamData != nullptr) // If it's already loaded in memory, use it directly stream = mSourceStreamData; else { stream = mStreamData; offset = mStreamOffset; } UINT32 bufferSize = info.numSamples * (info.bitDepth / 8); UINT8* sampleBuffer = (UINT8*)bs_stack_alloc(bufferSize); // Decompress from Ogg if (mDesc.format == AudioFormat::VORBIS) { OggVorbisDecoder reader; if (reader.open(stream, info, offset)) reader.read(sampleBuffer, info.numSamples); else LOGERR("Failed decompressing AudioClip stream."); } // Load directly else { stream->seek(offset); stream->read(sampleBuffer, bufferSize); } alGenBuffers(1, &mBufferId); gOAAudio()._writeToOpenALBuffer(mBufferId, sampleBuffer, info); mStreamData = nullptr; mStreamOffset = 0; mStreamSize = 0; bs_stack_free(sampleBuffer); } // Load compressed data for streaming from memory else if(mDesc.readMode == AudioReadMode::LoadCompressed) { // If reading from file, make a copy of data in memory, otherwise just take ownership of the existing buffer if (mStreamData->isFile()) { if (mSourceStreamData != nullptr) // If it's already loaded in memory, use it directly mStreamData = mSourceStreamData; else { UINT8* data = (UINT8*)bs_alloc(mStreamSize); mStreamData->seek(mStreamOffset); mStreamData->read(data, mStreamSize); mStreamData = bs_shared_ptr_new<MemoryDataStream>(data, mStreamSize); } mStreamOffset = 0; } } // Keep original stream for streaming from file else { // Do nothing } if (mDesc.format == AudioFormat::VORBIS && mDesc.readMode != AudioReadMode::LoadDecompressed) { mNeedsDecompression = true; if (mStreamData != nullptr) { if (!mVorbisReader.open(mStreamData, info, mStreamOffset)) LOGERR("Failed decompressing AudioClip stream."); } } } AudioClip::initialize(); }