Commit 3eb0f400 authored by David Reid's avatar David Reid

Add support for wide strings (wchar_t) to the resource manager.

parent 71b06a89
......@@ -43995,7 +43995,7 @@ MA_API ma_result ma_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo
}
static ma_result ma_vfs_open_and_read_file_ex(ma_vfs* pVFS, const char* pFilePath, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks, ma_uint32 allocationType)
static ma_result ma_vfs_open_and_read_file_ex(ma_vfs* pVFS, const char* pFilePath, const wchar_t* pFilePathW, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks, ma_uint32 allocationType)
{
ma_result result;
ma_vfs_file file;
......@@ -44016,7 +44016,11 @@ static ma_result ma_vfs_open_and_read_file_ex(ma_vfs* pVFS, const char* pFilePat
return MA_INVALID_ARGS;
}
result = ma_vfs_open(pVFS, pFilePath, MA_OPEN_MODE_READ, &file);
if (pFilePath != NULL) {
result = ma_vfs_open(pVFS, pFilePath, MA_OPEN_MODE_READ, &file);
} else {
result = ma_vfs_open_w(pVFS, pFilePathW, MA_OPEN_MODE_READ, &file);
}
if (result != MA_SUCCESS) {
return result;
}
......@@ -44056,9 +44060,14 @@ static ma_result ma_vfs_open_and_read_file_ex(ma_vfs* pVFS, const char* pFilePat
return MA_SUCCESS;
}
ma_result ma_vfs_open_and_read_file(ma_vfs* pVFS, const char* pFilePath, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks)
MA_API ma_result ma_vfs_open_and_read_file(ma_vfs* pVFS, const char* pFilePath, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks)
{
return ma_vfs_open_and_read_file_ex(pVFS, pFilePath, NULL, ppData, pSize, pAllocationCallbacks, 0 /*MA_ALLOCATION_TYPE_GENERAL*/);
}
MA_API ma_result ma_vfs_open_and_read_file_w(ma_vfs* pVFS, const wchar_t* pFilePath, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks)
{
return ma_vfs_open_and_read_file_ex(pVFS, pFilePath, ppData, pSize, pAllocationCallbacks, 0 /*MA_ALLOCATION_TYPE_GENERAL*/);
return ma_vfs_open_and_read_file_ex(pVFS, NULL, pFilePath, ppData, pSize, pAllocationCallbacks, 0 /*MA_ALLOCATION_TYPE_GENERAL*/);
}
......@@ -1120,6 +1120,7 @@ typedef struct
{
ma_resource_manager_data_buffer* pDataBuffer;
char* pFilePath;
wchar_t* pFilePathW;
ma_async_notification* pInitNotification; /* Signalled when the data buffer has been initialized and the format/channels/rate can be retrieved. */
ma_async_notification* pCompletedNotification; /* Signalled when the data buffer has been fully decoded. */
} loadDataBuffer;
......@@ -1143,6 +1144,7 @@ typedef struct
{
ma_resource_manager_data_stream* pDataStream;
char* pFilePath; /* Allocated when the job is posted, freed by the job thread after loading. */
wchar_t* pFilePathW; /* ^ As above ^. Only used if pFilePath is NULL. */
ma_async_notification* pNotification; /* Signalled after the first two pages have been decoded and frames can be read from the stream. */
} loadDataStream;
struct
......@@ -1337,11 +1339,15 @@ MA_API void ma_resource_manager_uninit(ma_resource_manager* pResourceManager);
/* Registration. */
MA_API ma_result ma_resource_manager_register_decoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate); /* Does not copy. Increments the reference count if already exists and returns MA_SUCCESS. */
MA_API ma_result ma_resource_manager_register_decoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);
MA_API ma_result ma_resource_manager_register_encoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, size_t sizeInBytes); /* Does not copy. Increments the reference count if already exists and returns MA_SUCCESS. */
MA_API ma_result ma_resource_manager_register_encoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, size_t sizeInBytes);
MA_API ma_result ma_resource_manager_unregister_data(ma_resource_manager* pResourceManager, const char* pName);
MA_API ma_result ma_resource_manager_unregister_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName);
/* Data Buffers. */
MA_API ma_result ma_resource_manager_data_buffer_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_uninit(ma_resource_manager_data_buffer* pDataBuffer);
MA_API ma_result ma_resource_manager_data_buffer_read_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64 frameIndex);
......@@ -1357,6 +1363,7 @@ MA_API ma_result ma_resource_manager_data_buffer_get_available_frames(ma_resourc
/* Data Streams. */
MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_uninit(ma_resource_manager_data_stream* pDataStream);
MA_API ma_result ma_resource_manager_data_stream_read_pcm_frames(ma_resource_manager_data_stream* pDataStream, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameIndex);
......@@ -1372,6 +1379,7 @@ MA_API ma_result ma_resource_manager_data_stream_get_available_frames(ma_resourc
/* Data Sources. */
MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager* pResourceManager, const char* pName, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_init_w(ma_resource_manager* pResourceManager, const wchar_t* pName, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_uninit(ma_resource_manager_data_source* pDataSource);
MA_API ma_result ma_resource_manager_data_source_read_pcm_frames(ma_resource_manager_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_resource_manager_data_source_seek_to_pcm_frame(ma_resource_manager_data_source* pDataSource, ma_uint64 frameIndex);
......@@ -5006,6 +5014,11 @@ static ma_uint32 ma_hash_string_32(const char* str)
return ma_hash_32(str, (int)strlen(str), MA_DEFAULT_HASH_SEED);
}
static ma_uint32 ma_hash_string_w_32(const wchar_t* str)
{
return ma_hash_32(str, (int)wcslen(str) * sizeof(*str), MA_DEFAULT_HASH_SEED);
}
......@@ -5614,18 +5627,22 @@ MA_API void ma_resource_manager_uninit(ma_resource_manager* pResourceManager)
}
static ma_result ma_resource_manager__init_decoder(ma_resource_manager* pResourceManager, const char* pFilePath, ma_decoder* pDecoder)
static ma_result ma_resource_manager__init_decoder(ma_resource_manager* pResourceManager, const char* pFilePath, const wchar_t* pFilePathW, ma_decoder* pDecoder)
{
ma_decoder_config config;
MA_ASSERT(pResourceManager != NULL);
MA_ASSERT(pFilePath != NULL);
MA_ASSERT(pFilePath != NULL || pFilePathW != NULL);
MA_ASSERT(pDecoder != NULL);
config = ma_decoder_config_init(pResourceManager->config.decodedFormat, pResourceManager->config.decodedChannels, pResourceManager->config.decodedSampleRate);
config.allocationCallbacks = pResourceManager->config.allocationCallbacks;
return ma_decoder_init_vfs(pResourceManager->config.pVFS, pFilePath, &config, pDecoder);
if (pFilePath != NULL) {
return ma_decoder_init_vfs(pResourceManager->config.pVFS, pFilePath, &config, pDecoder);
} else {
return ma_decoder_init_vfs_w(pResourceManager->config.pVFS, pFilePathW, &config, pDecoder);
}
}
static ma_result ma_resource_manager_data_buffer_init_connector(ma_resource_manager_data_buffer* pDataBuffer, ma_async_notification* pNotification)
......@@ -5800,16 +5817,17 @@ static ma_result ma_resource_manager_data_buffer_cb__get_length_in_pcm_frames(ma
return ma_resource_manager_data_buffer_get_length_in_pcm_frames((ma_resource_manager_data_buffer*)pDataSource, pLength);
}
static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 hashedName32, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer)
static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager* pResourceManager, const char* pFilePath, const wchar_t* pFilePathW, ma_uint32 hashedName32, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer)
{
ma_result result;
ma_resource_manager_data_buffer_node* pInsertPoint;
char* pFilePathCopy; /* Allocated here, freed in the job thread. */
char* pFilePathCopy = NULL; /* Allocated here, freed in the job thread. */
wchar_t* pFilePathWCopy = NULL;
ma_resource_manager_data_buffer_encoding dataBufferType;
ma_bool32 async;
MA_ASSERT(pResourceManager != NULL);
MA_ASSERT(pFilePath != NULL);
MA_ASSERT(pFilePath != NULL || pFilePathW != NULL);
MA_ASSERT(pDataBuffer != NULL);
MA_ZERO_OBJECT(pDataBuffer);
......@@ -5910,8 +5928,13 @@ static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager
ma_resource_manager_inline_notification initNotification;
/* We need a copy of the file path. We should probably make this more efficient, but for now we'll do a transient memory allocation. */
pFilePathCopy = ma_copy_string(pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
if (pFilePathCopy == NULL) {
if (pFilePath != NULL) {
pFilePathCopy = ma_copy_string(pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
} else {
pFilePathWCopy = ma_copy_string_w(pFilePathW, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
}
if (pFilePathCopy == NULL || pFilePathWCopy == NULL) {
if (pNotification != NULL) {
ma_async_notification_signal(pNotification, MA_NOTIFICATION_FAILED);
}
......@@ -5931,6 +5954,7 @@ static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager
job.order = ma_resource_manager_data_buffer_next_execution_order(pDataBuffer);
job.loadDataBuffer.pDataBuffer = pDataBuffer;
job.loadDataBuffer.pFilePath = pFilePathCopy;
job.loadDataBuffer.pFilePathW = pFilePathWCopy;
job.loadDataBuffer.pInitNotification = (waitInit == MA_TRUE) ? &initNotification : NULL;
job.loadDataBuffer.pCompletedNotification = pNotification;
result = ma_resource_manager_post_job(pResourceManager, &job);
......@@ -5947,6 +5971,7 @@ static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager
ma_resource_manager_data_buffer_node_remove(pResourceManager, pDataBuffer->pNode);
ma__free_from_callbacks(pDataBuffer->pNode, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_RESOURCE_MANAGER_DATA_BUFFER*/);
ma__free_from_callbacks(pFilePathCopy, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
ma__free_from_callbacks(pFilePathWCopy, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
return result;
}
......@@ -5961,7 +5986,7 @@ static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager
/* No decoding. Just store the file contents in memory. */
void* pData;
size_t sizeInBytes;
result = ma_vfs_open_and_read_file_ex(pResourceManager->config.pVFS, pFilePath, &pData, &sizeInBytes, &pResourceManager->config.allocationCallbacks, MA_ALLOCATION_TYPE_ENCODED_BUFFER);
result = ma_vfs_open_and_read_file_ex(pResourceManager->config.pVFS, pFilePath, pFilePathW, &pData, &sizeInBytes, &pResourceManager->config.allocationCallbacks, MA_ALLOCATION_TYPE_ENCODED_BUFFER);
if (result == MA_SUCCESS) {
pDataBuffer->pNode->data.encoded.pData = pData;
pDataBuffer->pNode->data.encoded.sizeInBytes = sizeInBytes;
......@@ -5970,7 +5995,7 @@ static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager
/* Decoding. */
ma_decoder decoder;
result = ma_resource_manager__init_decoder(pResourceManager, pFilePath, &decoder);
result = ma_resource_manager__init_decoder(pResourceManager, pFilePath, pFilePathW, &decoder);
if (result == MA_SUCCESS) {
ma_uint64 totalFrameCount;
ma_uint64 dataSizeInBytes;
......@@ -6100,7 +6125,7 @@ static ma_result ma_resource_manager_data_buffer_init_nolock(ma_resource_manager
return MA_SUCCESS;
}
MA_API ma_result ma_resource_manager_data_buffer_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer)
static ma_result ma_resource_manager_data_buffer_init_internal(ma_resource_manager* pResourceManager, const char* pFilePath, const wchar_t* pFilePathW, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer)
{
ma_result result;
ma_uint32 hashedName32;
......@@ -6109,23 +6134,37 @@ MA_API ma_result ma_resource_manager_data_buffer_init(ma_resource_manager* pReso
return MA_INVALID_ARGS;
}
if (pResourceManager == NULL || pFilePath == NULL) {
if (pResourceManager == NULL || (pFilePath == NULL && pFilePathW == NULL)) {
return MA_INVALID_ARGS;
}
/* Do as much set up before entering into the critical section to reduce our lock time as much as possible. */
hashedName32 = ma_hash_string_32(pFilePath);
if (pFilePath != NULL) {
hashedName32 = ma_hash_string_32(pFilePath);
} else {
hashedName32 = ma_hash_string_w_32(pFilePathW);
}
/* At this point we can now enter the critical section. */
ma_resource_manager_data_buffer_bst_lock(pResourceManager);
{
result = ma_resource_manager_data_buffer_init_nolock(pResourceManager, pFilePath, hashedName32, flags, pNotification, pDataBuffer);
result = ma_resource_manager_data_buffer_init_nolock(pResourceManager, pFilePath, pFilePathW, hashedName32, flags, pNotification, pDataBuffer);
}
ma_resource_manager_data_buffer_bst_unlock(pResourceManager);
return result;
}
MA_API ma_result ma_resource_manager_data_buffer_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer)
{
return ma_resource_manager_data_buffer_init_internal(pResourceManager, pFilePath, NULL, flags, pNotification, pDataBuffer);
}
MA_API ma_result ma_resource_manager_data_buffer_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_buffer* pDataBuffer)
{
return ma_resource_manager_data_buffer_init_internal(pResourceManager, NULL, pFilePath, flags, pNotification, pDataBuffer);
}
static ma_result ma_resource_manager_data_buffer_uninit_internal(ma_resource_manager_data_buffer* pDataBuffer)
{
MA_ASSERT(pDataBuffer != NULL);
......@@ -6519,16 +6558,20 @@ static ma_result ma_resource_manager_register_data_nolock(ma_resource_manager* p
return MA_SUCCESS;
}
static ma_result ma_resource_manager_register_data(ma_resource_manager* pResourceManager, const char* pName, ma_resource_manager_data_buffer_encoding type, ma_resource_manager_memory_buffer* pExistingData)
static ma_result ma_resource_manager_register_data(ma_resource_manager* pResourceManager, const char* pName, const wchar_t* pNameW, ma_resource_manager_data_buffer_encoding type, ma_resource_manager_memory_buffer* pExistingData)
{
ma_result result = MA_SUCCESS;
ma_uint32 hashedName32;
if (pResourceManager == NULL || pName == NULL) {
if (pResourceManager == NULL || (pName == NULL && pNameW == NULL)) {
return MA_INVALID_ARGS;
}
hashedName32 = ma_hash_string_32(pName);
if (pName != NULL) {
hashedName32 = ma_hash_string_32(pName);
} else {
hashedName32 = ma_hash_string_w_32(pNameW);
}
ma_resource_manager_data_buffer_bst_lock(pResourceManager);
{
......@@ -6539,7 +6582,7 @@ static ma_result ma_resource_manager_register_data(ma_resource_manager* pResourc
return result;
}
MA_API ma_result ma_resource_manager_register_decoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
static ma_result ma_resource_manager_register_decoded_data_internal(ma_resource_manager* pResourceManager, const char* pName, const wchar_t* pNameW, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
ma_resource_manager_memory_buffer data;
data.type = ma_resource_manager_data_buffer_encoding_decoded;
......@@ -6549,20 +6592,42 @@ MA_API ma_result ma_resource_manager_register_decoded_data(ma_resource_manager*
data.decoded.channels = channels;
data.decoded.sampleRate = sampleRate;
return ma_resource_manager_register_data(pResourceManager, pName, data.type, &data);
return ma_resource_manager_register_data(pResourceManager, pName, pNameW, data.type, &data);
}
MA_API ma_result ma_resource_manager_register_encoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, size_t sizeInBytes)
MA_API ma_result ma_resource_manager_register_decoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
return ma_resource_manager_register_decoded_data_internal(pResourceManager, pName, NULL, pData, frameCount, format, channels, sampleRate);
}
MA_API ma_result ma_resource_manager_register_decoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
{
return ma_resource_manager_register_decoded_data_internal(pResourceManager, NULL, pName, pData, frameCount, format, channels, sampleRate);
}
static ma_result ma_resource_manager_register_encoded_data_internal(ma_resource_manager* pResourceManager, const char* pName, const wchar_t* pNameW, const void* pData, size_t sizeInBytes)
{
ma_resource_manager_memory_buffer data;
data.type = ma_resource_manager_data_buffer_encoding_encoded;
data.encoded.pData = pData;
data.encoded.sizeInBytes = sizeInBytes;
return ma_resource_manager_register_data(pResourceManager, pName, data.type, &data);
return ma_resource_manager_register_data(pResourceManager, pName, pNameW, data.type, &data);
}
MA_API ma_result ma_resource_manager_register_encoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, size_t sizeInBytes)
{
return ma_resource_manager_register_encoded_data_internal(pResourceManager, pName, NULL, pData, sizeInBytes);
}
MA_API ma_result ma_resource_manager_register_encoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, size_t sizeInBytes)
{
return ma_resource_manager_register_encoded_data_internal(pResourceManager, NULL, pName, pData, sizeInBytes);
}
static ma_result ma_resource_manager_unregister_data_nolock(ma_resource_manager* pResourceManager, ma_uint32 hashedName32)
{
ma_result result;
......@@ -6593,16 +6658,21 @@ static ma_result ma_resource_manager_unregister_data_nolock(ma_resource_manager*
return MA_SUCCESS;
}
MA_API ma_result ma_resource_manager_unregister_data(ma_resource_manager* pResourceManager, const char* pName)
static ma_result ma_resource_manager_unregister_data_internal(ma_resource_manager* pResourceManager, const char* pName, const wchar_t* pNameW)
{
ma_result result;
ma_uint32 hashedName32;
if (pResourceManager == NULL || pName == NULL) {
if (pResourceManager == NULL || (pName == NULL && pNameW == NULL)) {
return MA_INVALID_ARGS;
}
hashedName32 = ma_hash_string_32(pName);
if (pName != NULL) {
hashedName32 = ma_hash_string_32(pName);
} else {
hashedName32 = ma_hash_string_w_32(pNameW);
}
/*
It's assumed that the data specified by pName was registered with a prior call to ma_resource_manager_register_encoded/decoded_data(). To unregister it, all
......@@ -6617,6 +6687,16 @@ MA_API ma_result ma_resource_manager_unregister_data(ma_resource_manager* pResou
return result;
}
MA_API ma_result ma_resource_manager_unregister_data(ma_resource_manager* pResourceManager, const char* pName)
{
return ma_resource_manager_unregister_data_internal(pResourceManager, pName, NULL);
}
MA_API ma_result ma_resource_manager_unregister_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName)
{
return ma_resource_manager_unregister_data_internal(pResourceManager, NULL, pName);
}
static ma_uint32 ma_resource_manager_data_stream_next_execution_order(ma_resource_manager_data_stream* pDataStream)
{
......@@ -6672,10 +6752,11 @@ static ma_result ma_resource_manager_data_stream_cb__get_length_in_pcm_frames(ma
return ma_resource_manager_data_stream_get_length_in_pcm_frames((ma_resource_manager_data_stream*)pDataSource, pLength);
}
MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_stream* pDataStream)
static ma_result ma_resource_manager_data_stream_init_internal(ma_resource_manager* pResourceManager, const char* pFilePath, const wchar_t* pFilePathW, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_stream* pDataStream)
{
ma_result result;
char* pFilePathCopy;
char* pFilePathCopy = NULL;
wchar_t* pFilePathWCopy = NULL;
ma_job job;
ma_bool32 waitBeforeReturning = MA_FALSE;
ma_resource_manager_inline_notification waitNotification;
......@@ -6701,7 +6782,7 @@ MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pReso
pDataStream->flags = flags;
pDataStream->result = MA_BUSY;
if (pResourceManager == NULL || pFilePath == NULL) {
if (pResourceManager == NULL || (pFilePath == NULL && pFilePathW == NULL)) {
if (pNotification != NULL) {
ma_async_notification_signal(pNotification, MA_NOTIFICATION_FAILED);
}
......@@ -6712,8 +6793,13 @@ MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pReso
/* We want all access to the VFS and the internal decoder to happen on the job thread just to keep things easier to manage for the VFS. */
/* We need a copy of the file path. We should probably make this more efficient, but for now we'll do a transient memory allocation. */
pFilePathCopy = ma_copy_string(pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
if (pFilePathCopy == NULL) {
if (pFilePath != NULL) {
pFilePathCopy = ma_copy_string(pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
} else {
pFilePathWCopy = ma_copy_string_w(pFilePathW, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
}
if (pFilePathCopy == NULL && pFilePathWCopy == NULL) {
if (pNotification != NULL) {
ma_async_notification_signal(pNotification, MA_NOTIFICATION_FAILED);
}
......@@ -6735,6 +6821,7 @@ MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pReso
job.order = ma_resource_manager_data_stream_next_execution_order(pDataStream);
job.loadDataStream.pDataStream = pDataStream;
job.loadDataStream.pFilePath = pFilePathCopy;
job.loadDataStream.pFilePathW = pFilePathWCopy;
job.loadDataStream.pNotification = (waitBeforeReturning == MA_TRUE) ? &waitNotification : pNotification;
result = ma_resource_manager_post_job(pResourceManager, &job);
if (result != MA_SUCCESS) {
......@@ -6746,7 +6833,8 @@ MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pReso
ma_resource_manager_inline_notification_uninit(&waitNotification);
}
ma__free_from_callbacks(pFilePathCopy, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
ma__free_from_callbacks(pFilePathCopy, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
ma__free_from_callbacks(pFilePathWCopy, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
return result;
}
......@@ -6763,6 +6851,16 @@ MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pReso
return MA_SUCCESS;
}
MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_stream* pDataStream)
{
return ma_resource_manager_data_stream_init_internal(pResourceManager, pFilePath, NULL, flags, pNotification, pDataStream);
}
MA_API ma_result ma_resource_manager_data_stream_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_stream* pDataStream)
{
return ma_resource_manager_data_stream_init_internal(pResourceManager, NULL, pFilePath, flags, pNotification, pDataStream);
}
MA_API ma_result ma_resource_manager_data_stream_uninit(ma_resource_manager_data_stream* pDataStream)
{
ma_resource_manager_inline_notification freeEvent;
......@@ -7254,8 +7352,7 @@ MA_API ma_result ma_resource_manager_data_stream_get_available_frames(ma_resourc
}
MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager* pResourceManager, const char* pName, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_source* pDataSource)
static ma_result ma_resource_manager_data_source_preinit(ma_resource_manager* pResourceManager, ma_uint32 flags, ma_resource_manager_data_source* pDataSource)
{
if (pDataSource == NULL) {
return MA_INVALID_ARGS;
......@@ -7263,12 +7360,24 @@ MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager* pReso
MA_ZERO_OBJECT(pDataSource);
if (pResourceManager == NULL || pName == NULL) {
if (pResourceManager == NULL) {
return MA_INVALID_ARGS;
}
pDataSource->flags = flags;
return MA_SUCCESS;
}
MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager* pResourceManager, const char* pName, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_source* pDataSource)
{
ma_result result;
result = ma_resource_manager_data_source_preinit(pResourceManager, flags, pDataSource);
if (result != MA_SUCCESS) {
return result;
}
/* The data source itself is just a data stream or a data buffer. */
if ((flags & MA_DATA_SOURCE_FLAG_STREAM) != 0) {
return ma_resource_manager_data_stream_init(pResourceManager, pName, flags, pNotification, &pDataSource->stream);
......@@ -7277,6 +7386,23 @@ MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager* pReso
}
}
MA_API ma_result ma_resource_manager_data_source_init_w(ma_resource_manager* pResourceManager, const wchar_t* pName, ma_uint32 flags, ma_async_notification* pNotification, ma_resource_manager_data_source* pDataSource)
{
ma_result result;
result = ma_resource_manager_data_source_preinit(pResourceManager, flags, pDataSource);
if (result != MA_SUCCESS) {
return result;
}
/* The data source itself is just a data stream or a data buffer. */
if ((flags & MA_DATA_SOURCE_FLAG_STREAM) != 0) {
return ma_resource_manager_data_stream_init_w(pResourceManager, pName, flags, pNotification, &pDataSource->stream);
} else {
return ma_resource_manager_data_buffer_init_w(pResourceManager, pName, flags, pNotification, &pDataSource->buffer);
}
}
MA_API ma_result ma_resource_manager_data_source_uninit(ma_resource_manager_data_source* pDataSource)
{
if (pDataSource == NULL) {
......@@ -7505,7 +7631,7 @@ static ma_result ma_resource_manager_process_job__load_data_buffer(ma_resource_m
/* No decoding. Just store the file contents in memory. */
size_t sizeInBytes;
result = ma_vfs_open_and_read_file_ex(pResourceManager->config.pVFS, pJob->loadDataBuffer.pFilePath, &pData, &sizeInBytes, &pResourceManager->config.allocationCallbacks, MA_ALLOCATION_TYPE_ENCODED_BUFFER);
result = ma_vfs_open_and_read_file_ex(pResourceManager->config.pVFS, pJob->loadDataBuffer.pFilePath, pJob->loadDataBuffer.pFilePathW, &pData, &sizeInBytes, &pResourceManager->config.allocationCallbacks, MA_ALLOCATION_TYPE_ENCODED_BUFFER);
if (result == MA_SUCCESS) {
pDataBuffer->pNode->data.encoded.pData = pData;
pDataBuffer->pNode->data.encoded.sizeInBytes = sizeInBytes;
......@@ -7527,7 +7653,7 @@ static ma_result ma_resource_manager_process_job__load_data_buffer(ma_resource_m
goto done;
}
result = ma_resource_manager__init_decoder(pResourceManager, pJob->loadDataBuffer.pFilePath, pDecoder);
result = ma_resource_manager__init_decoder(pResourceManager, pJob->loadDataBuffer.pFilePath, pJob->loadDataBuffer.pFilePathW, pDecoder);
/* Make sure we never set the result code to MA_BUSY or else we'll get everything confused. */
if (result == MA_BUSY) {
......@@ -7615,7 +7741,8 @@ static ma_result ma_resource_manager_process_job__load_data_buffer(ma_resource_m
}
done:
ma__free_from_callbacks(pJob->loadDataBuffer.pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
ma__free_from_callbacks(pJob->loadDataBuffer.pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
ma__free_from_callbacks(pJob->loadDataBuffer.pFilePathW, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
/*
We need to set the result to at the very end to ensure no other threads try reading the data before we've fully initialized the object. Other threads
......@@ -7882,7 +8009,11 @@ static ma_result ma_resource_manager_process_job__load_data_stream(ma_resource_m
decoderConfig = ma_decoder_config_init(pResourceManager->config.decodedFormat, pResourceManager->config.decodedChannels, pResourceManager->config.decodedSampleRate);
decoderConfig.allocationCallbacks = pResourceManager->config.allocationCallbacks;
result = ma_decoder_init_vfs(pResourceManager->config.pVFS, pJob->loadDataStream.pFilePath, &decoderConfig, &pDataStream->decoder);
if (pJob->loadDataStream.pFilePath != NULL) {
result = ma_decoder_init_vfs(pResourceManager->config.pVFS, pJob->loadDataStream.pFilePath, &decoderConfig, &pDataStream->decoder);
} else {
result = ma_decoder_init_vfs_w(pResourceManager->config.pVFS, pJob->loadDataStream.pFilePathW, &decoderConfig, &pDataStream->decoder);
}
if (result != MA_SUCCESS) {
goto done;
}
......@@ -7913,7 +8044,8 @@ static ma_result ma_resource_manager_process_job__load_data_stream(ma_resource_m
result = MA_SUCCESS;
done:
ma__free_from_callbacks(pJob->loadDataStream.pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
ma__free_from_callbacks(pJob->loadDataStream.pFilePath, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
ma__free_from_callbacks(pJob->loadDataStream.pFilePathW, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_TRANSIENT_STRING*/);
/* We can only change the status away from MA_BUSY. If it's set to anything else it means an error has occurred somewhere or the uninitialization process has started (most likely). */
c89atomic_compare_and_swap_32(&pDataStream->result, MA_BUSY, result);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment