mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Remove some old code.
This commit is contained in:
@@ -7181,348 +7181,6 @@ static ma_data_source_vtable g_ma_resource_manager_data_buffer_vtable =
|
||||
ma_resource_manager_data_buffer_cb__get_length_in_pcm_frames
|
||||
};
|
||||
|
||||
#if 0
|
||||
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_data_source_config dataSourceConfig;
|
||||
ma_resource_manager_data_buffer_node* pInsertPoint;
|
||||
char* pFilePathCopy = NULL; /* Allocated here, freed in the job thread. */
|
||||
wchar_t* pFilePathWCopy = NULL;
|
||||
ma_bool32 async;
|
||||
ma_bool32 decode;
|
||||
|
||||
MA_ASSERT(pResourceManager != NULL);
|
||||
MA_ASSERT(pDataBuffer != NULL);
|
||||
|
||||
MA_ZERO_OBJECT(pDataBuffer);
|
||||
|
||||
dataSourceConfig = ma_data_source_config_init();
|
||||
dataSourceConfig.vtable = &g_ma_resource_manager_data_buffer_vtable;
|
||||
|
||||
result = ma_data_source_init(&dataSourceConfig, &pDataBuffer->ds);
|
||||
if (result != MA_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
pDataBuffer->pResourceManager = pResourceManager;
|
||||
pDataBuffer->flags = flags;
|
||||
|
||||
|
||||
/* The encoding of the data buffer is taken from the flags. */
|
||||
decode = (flags & MA_DATA_SOURCE_FLAG_DECODE) != 0;
|
||||
|
||||
/* The data buffer needs to be loaded by the calling thread if we're in synchronous mode. */
|
||||
async = (flags & MA_DATA_SOURCE_FLAG_ASYNC) != 0;
|
||||
|
||||
/*
|
||||
The first thing to do is find the insertion point. If it's already loaded it means we can just increment the reference counter and signal the event. Otherwise we
|
||||
need to do a full load.
|
||||
*/
|
||||
result = ma_resource_manager_data_buffer_node_insert_point(pResourceManager, hashedName32, &pInsertPoint);
|
||||
if (result == MA_ALREADY_EXISTS) {
|
||||
/* Fast path. The data buffer already exists. We just need to increment the reference counter and signal the event, if any. */
|
||||
pDataBuffer->pNode = pInsertPoint;
|
||||
|
||||
result = ma_resource_manager_data_buffer_node_increment_ref(pResourceManager, pDataBuffer->pNode, NULL);
|
||||
if (result != MA_SUCCESS) {
|
||||
return result; /* Should never happen. Failed to increment the reference count. */
|
||||
}
|
||||
|
||||
/*
|
||||
The existing node may be in the middle of loading. We need to wait for the node to finish
|
||||
loading before going any further or else we won't be able to initialize the connector. The
|
||||
alternative to this could be to initialize the connector via the job queue when the data
|
||||
source is being loaded asynchronously.
|
||||
*/
|
||||
if (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY && ma_resource_manager_is_threading_enabled(pResourceManager) && async) {
|
||||
/* Loading asynchronously. */
|
||||
|
||||
/* TODO: This needs to be improved so that when loading asynchronously we post a message to the job queue instead of just waiting. */
|
||||
if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_encoded) {
|
||||
while (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY) {
|
||||
ma_yield();
|
||||
}
|
||||
} else {
|
||||
while (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) {
|
||||
ma_yield();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Not loading asychronously. We need to wait for the sound to be fully decoded so we can initialize a connector. */
|
||||
while (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY) {
|
||||
if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
|
||||
/* We're not threading, so process the next job if there are any. */
|
||||
result = ma_resource_manager_process_next_job(pResourceManager);
|
||||
if (result == MA_NO_DATA_AVAILABLE || result == MA_JOB_QUIT) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* We're threading, so just keep spinning until some other thread finishes decoding of the original sound. */
|
||||
ma_yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = ma_resource_manager_data_buffer_init_connector(pDataBuffer, NULL);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_resource_manager_data_buffer_node_free(pDataBuffer->pResourceManager, pDataBuffer->pNode);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (pNotification != NULL) {
|
||||
ma_async_notification_signal(pNotification, MA_NOTIFICATION_COMPLETE);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
Slow path. The data for this buffer has not yet been initialized. The first thing to do is
|
||||
allocate the new data buffer node and insert it into the BST.
|
||||
|
||||
Note that there's a possiblity that we're calling this function because we're wanting to
|
||||
initialize a data buffer from an existing data buffer rather than by a file name. In this
|
||||
case the file path will be NULL. This means the caller has uninitialized the last reference
|
||||
to the underlying node. This is an invalid usage - the caller must ensure the existing data
|
||||
buffer stays valid while cloning.
|
||||
*/
|
||||
if (pFilePath == NULL && pFilePathW == NULL) {
|
||||
return MA_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
pDataBuffer->pNode = (ma_resource_manager_data_buffer_node*)ma__malloc_from_callbacks(sizeof(*pDataBuffer->pNode), &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_RESOURCE_MANAGER_DATA_BUFFER*/);
|
||||
if (pDataBuffer->pNode == NULL) {
|
||||
return MA_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
MA_ZERO_OBJECT(pDataBuffer->pNode);
|
||||
pDataBuffer->pNode->hashedName32 = hashedName32;
|
||||
pDataBuffer->pNode->refCount = 1; /* Always set to 1 by default (this is our first reference). */
|
||||
pDataBuffer->pNode->data.type = ma_resource_manager_data_supply_type_unknown; /* <-- We won't know this until we start decoding. */
|
||||
pDataBuffer->pNode->result = MA_BUSY; /* I think it's good practice to set the status to MA_BUSY by default. */
|
||||
|
||||
result = ma_resource_manager_data_buffer_node_insert_at(pResourceManager, pDataBuffer->pNode, pInsertPoint);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma__free_from_callbacks(pDataBuffer->pNode, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_RESOURCE_MANAGER_DATA_BUFFER*/);
|
||||
return result; /* Should never happen. Failed to insert the data buffer into the BST. */
|
||||
}
|
||||
|
||||
/*
|
||||
The new data buffer has been inserted into the BST. We now need to load the data. If we are loading synchronously we need to load
|
||||
everything from the calling thread because we may be in a situation where there are no job threads running and therefore the data
|
||||
will never get loaded. If we are loading asynchronously, we can assume at least one job thread exists and we can do everything
|
||||
from there.
|
||||
*/
|
||||
pDataBuffer->pNode->isDataOwnedByResourceManager = MA_TRUE;
|
||||
pDataBuffer->pNode->result = MA_BUSY;
|
||||
|
||||
if (async) {
|
||||
/* Asynchronous. Post to the job thread. */
|
||||
ma_job job;
|
||||
ma_bool32 waitInit = MA_FALSE;
|
||||
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. */
|
||||
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);
|
||||
}
|
||||
|
||||
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*/);
|
||||
return MA_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if ((flags & MA_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
|
||||
waitInit = MA_TRUE;
|
||||
ma_resource_manager_inline_notification_init(pResourceManager, &initNotification);
|
||||
}
|
||||
|
||||
/* We now have everything we need to post the job to the job thread. */
|
||||
job = ma_job_init(MA_JOB_LOAD_DATA_BUFFER);
|
||||
job.order = ma_resource_manager_data_buffer_node_next_execution_order(pDataBuffer->pNode);
|
||||
job.loadDataBuffer.pDataBuffer = pDataBuffer;
|
||||
job.loadDataBuffer.pFilePath = pFilePathCopy;
|
||||
job.loadDataBuffer.pFilePathW = pFilePathWCopy;
|
||||
job.loadDataBuffer.decode = decode;
|
||||
job.loadDataBuffer.pInitNotification = (waitInit == MA_TRUE) ? &initNotification : NULL;
|
||||
job.loadDataBuffer.pCompletedNotification = pNotification;
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
if (result != MA_SUCCESS) {
|
||||
/* Failed to post the job to the queue. Probably ran out of space. */
|
||||
if (pNotification != NULL) {
|
||||
ma_async_notification_signal(pNotification, MA_NOTIFICATION_FAILED);
|
||||
}
|
||||
|
||||
if (waitInit == MA_TRUE) {
|
||||
ma_resource_manager_inline_notification_uninit(&initNotification);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* If we're waiting for initialization of the connector, do so here before returning. */
|
||||
if (waitInit == MA_TRUE) {
|
||||
ma_resource_manager_inline_notification_wait(&initNotification);
|
||||
ma_resource_manager_inline_notification_uninit(&initNotification);
|
||||
}
|
||||
} else {
|
||||
/* Synchronous. Do everything here. */
|
||||
if (decode == MA_FALSE) {
|
||||
/* 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, pFilePathW, &pData, &sizeInBytes, &pResourceManager->config.allocationCallbacks, MA_ALLOCATION_TYPE_ENCODED_BUFFER);
|
||||
if (result == MA_SUCCESS) {
|
||||
ma_resource_manager_data_buffer_node_set_data_supply_type(pDataBuffer->pNode, ma_resource_manager_data_supply_type_encoded);
|
||||
pDataBuffer->pNode->data.encoded.pData = pData;
|
||||
pDataBuffer->pNode->data.encoded.sizeInBytes = sizeInBytes;
|
||||
}
|
||||
} else {
|
||||
/* Decoding. */
|
||||
ma_decoder decoder;
|
||||
|
||||
result = ma_resource_manager__init_decoder(pResourceManager, pFilePath, pFilePathW, &decoder);
|
||||
if (result == MA_SUCCESS) {
|
||||
ma_uint64 totalFrameCount;
|
||||
ma_uint64 dataSizeInBytes;
|
||||
void* pData = NULL;
|
||||
|
||||
pDataBuffer->pNode->data.decoded.format = decoder.outputFormat;
|
||||
pDataBuffer->pNode->data.decoded.channels = decoder.outputChannels;
|
||||
pDataBuffer->pNode->data.decoded.sampleRate = decoder.outputSampleRate;
|
||||
|
||||
totalFrameCount = ma_decoder_get_length_in_pcm_frames(&decoder);
|
||||
if (totalFrameCount > 0) {
|
||||
/* It's a known length. We can use an optimized allocation strategy in this case. */
|
||||
dataSizeInBytes = totalFrameCount * ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels);
|
||||
if (dataSizeInBytes <= MA_SIZE_MAX) {
|
||||
pData = ma__malloc_from_callbacks((size_t)dataSizeInBytes, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_DECODED_BUFFER*/);
|
||||
if (pData != NULL) {
|
||||
totalFrameCount = ma_decoder_read_pcm_frames(&decoder, pData, totalFrameCount);
|
||||
} else {
|
||||
result = MA_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
result = MA_TOO_BIG;
|
||||
}
|
||||
} else {
|
||||
/* It's an unknown length. We need to dynamically expand the buffer as we decode. To start with we allocate space for one page. We'll then double it as we need more space. */
|
||||
ma_uint64 bytesPerFrame;
|
||||
ma_uint64 pageSizeInFrames;
|
||||
ma_uint64 dataSizeInFrames;
|
||||
|
||||
bytesPerFrame = ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels);
|
||||
pageSizeInFrames = MA_RESOURCE_MANAGER_PAGE_SIZE_IN_MILLISECONDS * (decoder.outputSampleRate/1000);
|
||||
dataSizeInFrames = 0;
|
||||
|
||||
/* Keep loading, page-by-page. */
|
||||
for (;;) {
|
||||
ma_uint64 framesRead;
|
||||
|
||||
/* Expand the buffer if need be. */
|
||||
if (totalFrameCount + pageSizeInFrames > dataSizeInFrames) {
|
||||
ma_uint64 oldDataSizeInFrames;
|
||||
ma_uint64 oldDataSizeInBytes;
|
||||
ma_uint64 newDataSizeInFrames;
|
||||
ma_uint64 newDataSizeInBytes;
|
||||
void* pNewData;
|
||||
|
||||
oldDataSizeInFrames = (dataSizeInFrames);
|
||||
newDataSizeInFrames = (dataSizeInFrames == 0) ? pageSizeInFrames : dataSizeInFrames * 2;
|
||||
|
||||
oldDataSizeInBytes = bytesPerFrame * oldDataSizeInFrames;
|
||||
newDataSizeInBytes = bytesPerFrame * newDataSizeInFrames;
|
||||
|
||||
if (newDataSizeInBytes > MA_SIZE_MAX) {
|
||||
result = MA_TOO_BIG;
|
||||
break;
|
||||
}
|
||||
|
||||
pNewData = ma__realloc_from_callbacks(pData, (size_t)newDataSizeInBytes, (size_t)oldDataSizeInBytes, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_DECODED_BUFFER*/);
|
||||
if (pNewData == NULL) {
|
||||
ma__free_from_callbacks(pData, &pResourceManager->config.allocationCallbacks/*, MA_ALLOCATION_TYPE_DECODED_BUFFER*/);
|
||||
result = MA_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
pData = pNewData;
|
||||
dataSizeInFrames = newDataSizeInFrames;
|
||||
}
|
||||
|
||||
framesRead = ma_decoder_read_pcm_frames(&decoder, ma_offset_ptr(pData, bytesPerFrame * totalFrameCount), pageSizeInFrames);
|
||||
totalFrameCount += framesRead;
|
||||
|
||||
if (framesRead < pageSizeInFrames) {
|
||||
/* We've reached the end. As we were loading we were doubling the size of the buffer each time we needed more memory. Let's try reducing this by doing a final realloc(). */
|
||||
size_t newDataSizeInBytes = (size_t)(totalFrameCount * bytesPerFrame);
|
||||
size_t oldDataSizeInBytes = (size_t)(dataSizeInFrames * bytesPerFrame);
|
||||
void* pNewData = ma__realloc_from_callbacks(pData, newDataSizeInBytes, oldDataSizeInBytes, &pResourceManager->config.allocationCallbacks);
|
||||
if (pNewData != NULL) {
|
||||
pData = pNewData;
|
||||
}
|
||||
|
||||
/* We're done, so get out of the loop. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == MA_SUCCESS) {
|
||||
pDataBuffer->pNode->data.decoded.pData = pData;
|
||||
pDataBuffer->pNode->data.decoded.totalFrameCount = totalFrameCount;
|
||||
pDataBuffer->pNode->data.decoded.decodedFrameCount = totalFrameCount; /* We've decoded everything. */
|
||||
ma_resource_manager_data_buffer_node_set_data_supply_type(pDataBuffer->pNode, ma_resource_manager_data_supply_type_decoded);
|
||||
} else {
|
||||
pDataBuffer->pNode->data.decoded.pData = NULL;
|
||||
pDataBuffer->pNode->data.decoded.totalFrameCount = 0;
|
||||
pDataBuffer->pNode->data.decoded.decodedFrameCount = 0;
|
||||
ma_resource_manager_data_buffer_node_set_data_supply_type(pDataBuffer->pNode, ma_resource_manager_data_supply_type_unknown);
|
||||
}
|
||||
|
||||
ma_decoder_uninit(&decoder);
|
||||
}
|
||||
}
|
||||
|
||||
/* When loading synchronously we need to initialize the connector straight away. */
|
||||
if (result == MA_SUCCESS) {
|
||||
result = ma_resource_manager_data_buffer_init_connector(pDataBuffer, NULL);
|
||||
}
|
||||
|
||||
pDataBuffer->pNode->result = result;
|
||||
}
|
||||
|
||||
/* If we failed to initialize make sure we fire the event and free memory. */
|
||||
if (result != MA_SUCCESS) {
|
||||
if (pNotification != NULL) {
|
||||
ma_async_notification_signal(pNotification, MA_NOTIFICATION_COMPLETE);
|
||||
}
|
||||
|
||||
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*/);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* We'll need to fire the event if we have one in synchronous mode. */
|
||||
if (async == MA_FALSE) {
|
||||
if (pNotification != NULL) {
|
||||
ma_async_notification_signal(pNotification, MA_NOTIFICATION_COMPLETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ma_result ma_resource_manager_data_buffer_init_internal(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;
|
||||
|
||||
Reference in New Issue
Block a user