ma_uint32hashedName32;/* The hashed name. This is the key. */
ma_uint32refCount;
ma_resultresult;/* Result from asynchronous loading. When loading set to MA_BUSY. When fully loaded set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. */
volatilema_resultresult;/* Result from asynchronous loading. When loading set to MA_BUSY. When fully loaded set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. */
ma_uint32executionCounter;/* For allocating execution orders for jobs. */
ma_uint32executionPointer;/* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
ma_bool32isDataOwnedByResourceManager;/* Set to true when the underlying data buffer was allocated the resource manager. Set to false if it is owned by the application (via ma_resource_manager_register_*()). */
ma_uint32executionPointer;/* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
/* Written by the public API, read by the job thread. */
ma_bool32isLooping;/* Whether or not the stream is looping. It's important to set the looping flag at the data stream level for smooth loop transitions. */
volatilema_bool32isLooping;/* Whether or not the stream is looping. It's important to set the looping flag at the data stream level for smooth loop transitions. */
/* Written by the job thread, read by the public API. */
void*pPageData;/* Buffer containing the decoded data of each page. Allocated once at initialization time. */
ma_uint32pageFrameCount[2];/* The number of valid PCM frames in each page. Used to determine the last valid frame. */
volatilema_uint32pageFrameCount[2];/* The number of valid PCM frames in each page. Used to determine the last valid frame. */
/* Written and read by both the public API and the job thread. */
ma_resultresult;/* Result from asynchronous loading. When loading set to MA_BUSY. When initialized set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. If an error occurs when loading, set to an error code. */
ma_bool32isDecoderAtEnd;/* Whether or not the decoder has reached the end. */
ma_bool32isPageValid[2];/* Booleans to indicate whether or not a page is valid. Set to false by the public API, set to true by the job thread. Set to false as the pages are consumed, true when they are filled. */
ma_bool32seekCounter;/* When 0, no seeking is being performed. When > 0, a seek is being performed and reading should be delayed with MA_BUSY. */
volatilema_resultresult;/* Result from asynchronous loading. When loading set to MA_BUSY. When initialized set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. If an error occurs when loading, set to an error code. */
volatilema_bool32isDecoderAtEnd;/* Whether or not the decoder has reached the end. */
volatilema_bool32isPageValid[2];/* Booleans to indicate whether or not a page is valid. Set to false by the public API, set to true by the job thread. Set to false as the pages are consumed, true when they are filled. */
volatilema_bool32seekCounter;/* When 0, no seeking is being performed. When > 0, a seek is being performed and reading should be delayed with MA_BUSY. */
};
structma_resource_manager_data_source
...
...
@@ -1529,8 +1529,8 @@ struct ma_sound
ma_engine*pEngine;/* A pointer to the object that owns this sound. */
ma_data_source*pDataSource;
ma_sound_group*pGroup;/* The group the sound is attached to. */
ma_sound*pPrevSoundInGroup;
ma_sound*pNextSoundInGroup;
volatilema_sound*pPrevSoundInGroup;
volatilema_sound*pNextSoundInGroup;
ma_engine_effecteffect;/* The effect containing all of the information for spatialization, pitching, etc. */
floatvolume;
ma_uint64seekTarget;/* The PCM frame index to seek to in the mixing thread. Set to (~(ma_uint64)0) to not perform any seeking. */
...
...
@@ -1538,10 +1538,10 @@ struct ma_sound
ma_uint64startDelayInEngineFrames;/* In the engine's sample rate. */
ma_uint64stopDelayInEngineFrames;/* In the engine's sample rate. */
ma_uint64stopDelayInEngineFramesRemaining;/* The number of frames relative to the engine's clock before the sound is stopped. */
ma_bool32isPlaying;/* False by default. Sounds need to be explicitly started with ma_sound_start() and stopped with ma_sound_stop(). */
ma_bool32isMixing;
ma_bool32isLooping;/* False by default. */
ma_bool32atEnd;
volatilema_bool32isPlaying;/* False by default. Sounds need to be explicitly started with ma_sound_start() and stopped with ma_sound_stop(). */
volatilema_bool32isMixing;
volatilema_bool32isLooping;/* False by default. */
volatilema_bool32atEnd;
ma_bool32ownsDataSource;
ma_bool32_isInternal;/* A marker to indicate the sound is managed entirely by the engine. This will be set to true when the sound is created internally by ma_engine_play_sound(). */
ma_engine_effecteffect;/* The main effect for panning, etc. This is set on the mixer at initialisation time. */
ma_mixermixer;
ma_mutexlock;/* Only used by ma_sound_init_*() and ma_sound_uninit(). Not used in the mixing thread. */
...
...
@@ -1562,7 +1562,7 @@ struct ma_sound_group
ma_uint64startDelayInEngineFrames;
ma_uint64stopDelayInEngineFrames;/* In the engine's sample rate. */
ma_uint64stopDelayInEngineFramesRemaining;/* The number of frames relative to the engine's clock before the sound is stopped. */
ma_bool32isPlaying;/* True by default. Sound groups can be stopped with ma_sound_stop() and resumed with ma_sound_start(). Also affects children. */
volatilema_bool32isPlaying;/* True by default. Sound groups can be stopped with ma_sound_stop() and resumed with ma_sound_start(). Also affects children. */
The page we're on is valid so we must have some frames available. We need to make sure that we don't overflow into the next page, even if it's valid. The reason is
that the unmap process will only post an update for one page at a time. Keeping mapping tied to page boundaries makes this simpler.
returnMA_BUSY;/* There are no frames available, but we're not marked as EOF so we might have caught up to the job thread. Need to return MA_BUSY and wait for more data. */
*pIsLooping=c89atomic_load_32((ma_bool32*)&pDataStream->isLooping);/* Naughty const-cast. Value won't change from here in practice (maybe from another thread). */
The first thing to do is find an available sound. We will only be doing a forward iteration here so we should be able to do this part without locking. A
sound will be available for recycling if it's marked as internal and is at the end.
The sound should never be in a playing state when this is called. It *can*, however, but in the middle of mixing in the mixing thread. It needs to finish
mixing before being uninitialized completely, but that is done at a higher level to this function.
*/
MA_ASSERT(pSound->isPlaying==MA_FALSE);
MA_ASSERT(ma_sound_is_playing(pSound)==MA_FALSE);
/*
We want the creation and deletion of sounds to be supported across multiple threads. An application may have any thread that want's to call