mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-29 19:54:05 +02:00
Make ma_sound_init_copy() more generic.
The copying of the data source is now done generically through the new data source copying system rather than being restricted to just the resource manager.
This commit is contained in:
+30
-35
@@ -11781,12 +11781,7 @@ struct ma_sound
|
|||||||
ma_uint32 processingCacheCap;
|
ma_uint32 processingCacheCap;
|
||||||
ma_bool8 ownsDataSource;
|
ma_bool8 ownsDataSource;
|
||||||
|
|
||||||
/*
|
|
||||||
We're declaring a resource manager data source object here to save us a malloc when loading a
|
|
||||||
sound via the resource manager, which I *think* will be the most common scenario.
|
|
||||||
*/
|
|
||||||
#ifndef MA_NO_RESOURCE_MANAGER
|
#ifndef MA_NO_RESOURCE_MANAGER
|
||||||
ma_resource_manager_data_source* pResourceManagerDataSource;
|
|
||||||
ma_async_notification_callbacks resourceManagerDoneNotification;
|
ma_async_notification_callbacks resourceManagerDoneNotification;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -87538,8 +87533,8 @@ MA_API ma_result ma_sound_init_from_file_internal(ma_engine* pEngine, const ma_s
|
|||||||
*/
|
*/
|
||||||
flags = pConfig->flags | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT;
|
flags = pConfig->flags | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT;
|
||||||
|
|
||||||
pSound->pResourceManagerDataSource = (ma_resource_manager_data_source*)ma_malloc(sizeof(*pSound->pResourceManagerDataSource), &pEngine->allocationCallbacks);
|
pSound->pDataSource = (ma_resource_manager_data_source*)ma_malloc(sizeof(ma_resource_manager_data_source), &pEngine->allocationCallbacks);
|
||||||
if (pSound->pResourceManagerDataSource == NULL) {
|
if (pSound->pDataSource == NULL) {
|
||||||
return MA_OUT_OF_MEMORY;
|
return MA_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87572,9 +87567,9 @@ MA_API ma_result ma_sound_init_from_file_internal(ma_engine* pEngine, const ma_s
|
|||||||
resourceManagerDataSourceConfig.loopPointBegInPCMFrames = pConfig->loopPointBegInPCMFrames;
|
resourceManagerDataSourceConfig.loopPointBegInPCMFrames = pConfig->loopPointBegInPCMFrames;
|
||||||
resourceManagerDataSourceConfig.loopPointEndInPCMFrames = pConfig->loopPointEndInPCMFrames;
|
resourceManagerDataSourceConfig.loopPointEndInPCMFrames = pConfig->loopPointEndInPCMFrames;
|
||||||
|
|
||||||
result = ma_resource_manager_data_source_init_ex(pEngine->pResourceManager, &resourceManagerDataSourceConfig, pSound->pResourceManagerDataSource);
|
result = ma_resource_manager_data_source_init_ex(pEngine->pResourceManager, &resourceManagerDataSourceConfig, (ma_resource_manager_data_source*)pSound->pDataSource);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
ma_free(pSound->pResourceManagerDataSource, &pEngine->allocationCallbacks);
|
ma_free(pSound->pDataSource, &pEngine->allocationCallbacks);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87584,12 +87579,12 @@ MA_API ma_result ma_sound_init_from_file_internal(ma_engine* pEngine, const ma_s
|
|||||||
config = *pConfig;
|
config = *pConfig;
|
||||||
config.pFilePath = NULL;
|
config.pFilePath = NULL;
|
||||||
config.pFilePathW = NULL;
|
config.pFilePathW = NULL;
|
||||||
config.pDataSource = pSound->pResourceManagerDataSource;
|
config.pDataSource = pSound->pDataSource;
|
||||||
|
|
||||||
result = ma_sound_init_from_data_source_internal(pEngine, &config, pSound);
|
result = ma_sound_init_from_data_source_internal(pEngine, &config, pSound);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
ma_resource_manager_data_source_uninit(pSound->pResourceManagerDataSource);
|
ma_resource_manager_data_source_uninit((ma_resource_manager_data_source*)pSound->pDataSource);
|
||||||
ma_free(pSound->pResourceManagerDataSource, &pEngine->allocationCallbacks);
|
ma_free(pSound->pDataSource, &pEngine->allocationCallbacks);
|
||||||
MA_ZERO_OBJECT(pSound);
|
MA_ZERO_OBJECT(pSound);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -87637,6 +87632,8 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
|
|||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
ma_sound_config config;
|
ma_sound_config config;
|
||||||
|
const ma_data_source_vtable* pDataSourceVTable;
|
||||||
|
ma_data_source* pNewDataSource;
|
||||||
|
|
||||||
result = ma_sound_preinit(pEngine, pSound);
|
result = ma_sound_preinit(pEngine, pSound);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
@@ -87647,38 +87644,38 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
|
|||||||
return MA_INVALID_ARGS;
|
return MA_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cloning only works for data buffers (not streams) that are loaded from the resource manager. */
|
pDataSourceVTable = ma_data_source_get_vtable(pExistingSound->pDataSource);
|
||||||
if (pExistingSound->pResourceManagerDataSource == NULL) {
|
if (pDataSourceVTable == NULL) {
|
||||||
return MA_INVALID_OPERATION;
|
return MA_INVALID_OPERATION; /* Sound is not tied to a data source. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (pDataSourceVTable->onSizeof == NULL || pDataSourceVTable->onCopy == NULL) {
|
||||||
We need to make a clone of the data source. If the data source is not a data buffer (i.e. a stream)
|
return MA_INVALID_OPERATION; /* Data source is not copyable. */
|
||||||
this will fail.
|
}
|
||||||
*/
|
|
||||||
pSound->pResourceManagerDataSource = (ma_resource_manager_data_source*)ma_malloc(sizeof(*pSound->pResourceManagerDataSource), &pEngine->allocationCallbacks);
|
pNewDataSource = (ma_data_source*)ma_malloc(pDataSourceVTable->onSizeof(), &pEngine->allocationCallbacks);
|
||||||
if (pSound->pResourceManagerDataSource == NULL) {
|
if (pNewDataSource == NULL) {
|
||||||
return MA_OUT_OF_MEMORY;
|
return MA_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = ma_resource_manager_data_source_init_copy(pEngine->pResourceManager, pExistingSound->pResourceManagerDataSource, pSound->pResourceManagerDataSource);
|
result = ma_data_source_init_copy(pExistingSound->pDataSource, pNewDataSource);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
ma_free(pSound->pResourceManagerDataSource, &pEngine->allocationCallbacks);
|
ma_free(pNewDataSource, &pEngine->allocationCallbacks);
|
||||||
return result;
|
return result; /* Copying probably not supported by the data source. */
|
||||||
}
|
}
|
||||||
|
|
||||||
config = ma_sound_config_init(pEngine);
|
config = ma_sound_config_init(pEngine);
|
||||||
config.pDataSource = pSound->pResourceManagerDataSource;
|
config.pDataSource = pNewDataSource;
|
||||||
config.flags = flags;
|
config.flags = flags;
|
||||||
config.pInitialAttachment = pGroup;
|
config.pInitialAttachment = pGroup;
|
||||||
config.monoExpansionMode = pExistingSound->engineNode.monoExpansionMode;
|
config.monoExpansionMode = pExistingSound->engineNode.monoExpansionMode;
|
||||||
config.volumeSmoothTimeInPCMFrames = pExistingSound->engineNode.volumeSmoothTimeInPCMFrames;
|
config.volumeSmoothTimeInPCMFrames = pExistingSound->engineNode.volumeSmoothTimeInPCMFrames;
|
||||||
config.pNotifications = pNotifications;
|
config.pNotifications = pNotifications;
|
||||||
|
|
||||||
result = ma_sound_init_from_data_source_internal(pEngine, &config, pSound);
|
result = ma_sound_init_from_data_source_internal(pEngine, &config, pSound);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
ma_resource_manager_data_source_uninit(pSound->pResourceManagerDataSource);
|
if (pDataSourceVTable->onUninit) { pDataSourceVTable->onUninit(pNewDataSource); }
|
||||||
ma_free(pSound->pResourceManagerDataSource, &pEngine->allocationCallbacks);
|
ma_free(pNewDataSource, &pEngine->allocationCallbacks);
|
||||||
MA_ZERO_OBJECT(pSound);
|
MA_ZERO_OBJECT(pSound);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -87752,16 +87749,14 @@ MA_API void ma_sound_uninit(ma_sound* pSound)
|
|||||||
pSound->pProcessingCache = NULL;
|
pSound->pProcessingCache = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Once the sound is detached from the group we can guarantee that it won't be referenced by the mixer thread which means it's safe for us to destroy the data source. */
|
|
||||||
#ifndef MA_NO_RESOURCE_MANAGER
|
|
||||||
if (pSound->ownsDataSource) {
|
if (pSound->ownsDataSource) {
|
||||||
ma_resource_manager_data_source_uninit(pSound->pResourceManagerDataSource);
|
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pSound->pDataSource;
|
||||||
ma_free(pSound->pResourceManagerDataSource, &pSound->engineNode.pEngine->allocationCallbacks);
|
MA_ASSERT(pDataSourceBase != NULL);
|
||||||
|
|
||||||
|
if (pDataSourceBase->pVTable->onUninit) { pDataSourceBase->pVTable->onUninit(pSound->pDataSource); }
|
||||||
|
ma_free(pSound->pDataSource, &pSound->engineNode.pEngine->allocationCallbacks);
|
||||||
pSound->pDataSource = NULL;
|
pSound->pDataSource = NULL;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
MA_ASSERT(pSound->ownsDataSource == MA_FALSE);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MA_API ma_engine* ma_sound_get_engine(const ma_sound* pSound)
|
MA_API ma_engine* ma_sound_get_engine(const ma_sound* pSound)
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ int main(int argc, char** argv)
|
|||||||
ma_engine_start(&engine);
|
ma_engine_start(&engine);
|
||||||
|
|
||||||
/* Rapidly create and delete sounds. */
|
/* Rapidly create and delete sounds. */
|
||||||
|
#if 1
|
||||||
{
|
{
|
||||||
ma_sound* pSound = NULL;
|
ma_sound* pSound = NULL;
|
||||||
ma_uint32 soundCount = 10;
|
ma_uint32 soundCount = 10;
|
||||||
@@ -124,6 +125,26 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
sounds.clear();
|
sounds.clear();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
ma_sound baseSound;
|
||||||
|
|
||||||
|
result = ma_sound_init_from_file(&engine, pFilePaths[0], MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC, NULL, NULL, &baseSound);
|
||||||
|
if (result == MA_SUCCESS) {
|
||||||
|
ma_sound copiedSound;
|
||||||
|
|
||||||
|
result = ma_sound_init_copy(&engine, &baseSound, 0, NULL, NULL, &copiedSound);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
printf("Failed to copy sound.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_sound_start(&copiedSound);
|
||||||
|
ma_sleep(5000);
|
||||||
|
|
||||||
|
ma_sound_uninit(&copiedSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ma_engine_uninit(&engine);
|
ma_engine_uninit(&engine);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user