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

API CHANGE: Add channel maps to ma_data_source_get_data_format().

This commit also removes the onGetChannelMap callback from the decoding
backend vtable.
parent def31404
...@@ -95,8 +95,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libvorbis = ...@@ -95,8 +95,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libvorbis =
ma_decoding_backend_init_file__libvorbis, ma_decoding_backend_init_file__libvorbis,
NULL, /* onInitFileW() */ NULL, /* onInitFileW() */
NULL, /* onInitMemory() */ NULL, /* onInitMemory() */
ma_decoding_backend_uninit__libvorbis, ma_decoding_backend_uninit__libvorbis
ma_decoding_backend_get_channel_map__libvorbis
}; };
...@@ -172,8 +171,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libopus = ...@@ -172,8 +171,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libopus =
ma_decoding_backend_init_file__libopus, ma_decoding_backend_init_file__libopus,
NULL, /* onInitFileW() */ NULL, /* onInitFileW() */
NULL, /* onInitMemory() */ NULL, /* onInitMemory() */
ma_decoding_backend_uninit__libopus, ma_decoding_backend_uninit__libopus
ma_decoding_backend_get_channel_map__libopus
}; };
...@@ -233,7 +231,7 @@ int main(int argc, char** argv) ...@@ -233,7 +231,7 @@ int main(int argc, char** argv)
/* Initialize the device. */ /* Initialize the device. */
result = ma_data_source_get_data_format(&decoder, &format, &channels, &sampleRate); result = ma_data_source_get_data_format(&decoder, &format, &channels, &sampleRate, NULL, 0);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
printf("Failed to retrieve decoder data format."); printf("Failed to retrieve decoder data format.");
ma_decoder_uninit(&decoder); ma_decoder_uninit(&decoder);
......
...@@ -56,9 +56,9 @@ static ma_result ma_libopus_ds_seek(ma_data_source* pDataSource, ma_uint64 frame ...@@ -56,9 +56,9 @@ static ma_result ma_libopus_ds_seek(ma_data_source* pDataSource, ma_uint64 frame
return ma_libopus_seek_to_pcm_frame((ma_libopus*)pDataSource, frameIndex); return ma_libopus_seek_to_pcm_frame((ma_libopus*)pDataSource, frameIndex);
} }
static ma_result ma_libopus_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_libopus_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_libopus_get_data_format((ma_libopus*)pDataSource, pFormat, pChannels, pSampleRate, NULL, 0); return ma_libopus_get_data_format((ma_libopus*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_libopus_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_libopus_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
......
...@@ -57,9 +57,9 @@ static ma_result ma_libvorbis_ds_seek(ma_data_source* pDataSource, ma_uint64 fra ...@@ -57,9 +57,9 @@ static ma_result ma_libvorbis_ds_seek(ma_data_source* pDataSource, ma_uint64 fra
return ma_libvorbis_seek_to_pcm_frame((ma_libvorbis*)pDataSource, frameIndex); return ma_libvorbis_seek_to_pcm_frame((ma_libvorbis*)pDataSource, frameIndex);
} }
static ma_result ma_libvorbis_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_libvorbis_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_libvorbis_get_data_format((ma_libvorbis*)pDataSource, pFormat, pChannels, pSampleRate, NULL, 0); return ma_libvorbis_get_data_format((ma_libvorbis*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_libvorbis_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_libvorbis_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
......
...@@ -5941,7 +5941,7 @@ typedef struct ...@@ -5941,7 +5941,7 @@ typedef struct
{ {
ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead); ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex); ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex);
ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate); ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor); ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength); ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
} ma_data_source_vtable; } ma_data_source_vtable;
...@@ -5973,7 +5973,7 @@ MA_API void ma_data_source_uninit(ma_data_source* pDataSource); ...@@ -5973,7 +5973,7 @@ MA_API void ma_data_source_uninit(ma_data_source* pDataSource);
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop); /* Must support pFramesOut = NULL in which case a forward seek should be performed. */ MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop); /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked, ma_bool32 loop); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount); */ MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked, ma_bool32 loop); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount); */
MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex); MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex);
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate); MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor); MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength); /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */ MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength); /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames); MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
...@@ -6151,7 +6151,6 @@ typedef struct ...@@ -6151,7 +6151,6 @@ typedef struct
ma_result (* onInitFileW )(void* pUserData, const wchar_t* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend); /* Optional. */ ma_result (* onInitFileW )(void* pUserData, const wchar_t* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend); /* Optional. */
ma_result (* onInitMemory )(void* pUserData, const void* pData, size_t dataSize, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend); /* Optional. */ ma_result (* onInitMemory )(void* pUserData, const void* pData, size_t dataSize, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend); /* Optional. */
void (* onUninit )(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks); void (* onUninit )(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks);
ma_result (* onGetChannelMap)(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap);
} ma_decoding_backend_vtable; } ma_decoding_backend_vtable;
...@@ -42300,6 +42299,10 @@ static void ma_get_standard_channel_map_sndio(ma_uint32 channels, ma_channel* pC ...@@ -42300,6 +42299,10 @@ static void ma_get_standard_channel_map_sndio(ma_uint32 channels, ma_channel* pC
MA_API void ma_get_standard_channel_map(ma_standard_channel_map standardChannelMap, ma_uint32 channels, ma_channel* pChannelMap) MA_API void ma_get_standard_channel_map(ma_standard_channel_map standardChannelMap, ma_uint32 channels, ma_channel* pChannelMap)
{ {
if (pChannelMap == NULL || channels == 0) {
return;
}
switch (standardChannelMap) switch (standardChannelMap)
{ {
case ma_standard_channel_map_alsa: case ma_standard_channel_map_alsa:
...@@ -43523,7 +43526,7 @@ MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, voi ...@@ -43523,7 +43526,7 @@ MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, voi
We need to know the data format so we can advance the output buffer as we read frames. If this We need to know the data format so we can advance the output buffer as we read frames. If this
fails, chaining will not work and we'll just read as much as we can from the current source. fails, chaining will not work and we'll just read as much as we can from the current source.
*/ */
if (ma_data_source_get_data_format(pDataSource, &format, &channels, NULL) != MA_SUCCESS) { if (ma_data_source_get_data_format(pDataSource, &format, &channels, NULL, NULL, 0) != MA_SUCCESS) {
result = ma_data_source_resolve_current(pDataSource, (ma_data_source**)&pCurrentDataSource); result = ma_data_source_resolve_current(pDataSource, (ma_data_source**)&pCurrentDataSource);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; return result;
...@@ -43650,7 +43653,7 @@ MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, m ...@@ -43650,7 +43653,7 @@ MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, m
return pDataSourceBase->vtable->onSeek(pDataSource, pDataSourceBase->rangeBegInFrames + frameIndex); return pDataSourceBase->vtable->onSeek(pDataSource, pDataSourceBase->rangeBegInFrames + frameIndex);
} }
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource; ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
ma_result result; ma_result result;
...@@ -43658,17 +43661,19 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_ ...@@ -43658,17 +43661,19 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_
ma_uint32 channels; ma_uint32 channels;
ma_uint32 sampleRate; ma_uint32 sampleRate;
/* Initialize to defaults for safety just in case the data source does not implement this callback. */
if (pFormat != NULL) { if (pFormat != NULL) {
*pFormat = ma_format_unknown; *pFormat = ma_format_unknown;
} }
if (pChannels != NULL) { if (pChannels != NULL) {
*pChannels = 0; *pChannels = 0;
} }
if (pSampleRate != NULL) { if (pSampleRate != NULL) {
*pSampleRate = 0; *pSampleRate = 0;
} }
if (pChannelMap != NULL) {
MA_ZERO_MEMORY(pChannelMap, sizeof(*pChannelMap) * channelMapCap);
}
if (pDataSourceBase == NULL) { if (pDataSourceBase == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
...@@ -43678,7 +43683,7 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_ ...@@ -43678,7 +43683,7 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_
return MA_NOT_IMPLEMENTED; return MA_NOT_IMPLEMENTED;
} }
result = pDataSourceBase->vtable->onGetDataFormat(pDataSource, &format, &channels, &sampleRate); result = pDataSourceBase->vtable->onGetDataFormat(pDataSource, &format, &channels, &sampleRate, pChannelMap, channelMapCap);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; return result;
} }
...@@ -43693,6 +43698,8 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_ ...@@ -43693,6 +43698,8 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_
*pSampleRate = sampleRate; *pSampleRate = sampleRate;
} }
/* Channel map was passed in directly to the callback. This is safe due to the channelMapCap parameter. */
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -43988,13 +43995,14 @@ static ma_result ma_audio_buffer_ref__data_source_on_seek(ma_data_source* pDataS ...@@ -43988,13 +43995,14 @@ static ma_result ma_audio_buffer_ref__data_source_on_seek(ma_data_source* pDataS
return ma_audio_buffer_ref_seek_to_pcm_frame((ma_audio_buffer_ref*)pDataSource, frameIndex); return ma_audio_buffer_ref_seek_to_pcm_frame((ma_audio_buffer_ref*)pDataSource, frameIndex);
} }
static ma_result ma_audio_buffer_ref__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_audio_buffer_ref__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
ma_audio_buffer_ref* pAudioBufferRef = (ma_audio_buffer_ref*)pDataSource; ma_audio_buffer_ref* pAudioBufferRef = (ma_audio_buffer_ref*)pDataSource;
*pFormat = pAudioBufferRef->format; *pFormat = pAudioBufferRef->format;
*pChannels = pAudioBufferRef->channels; *pChannels = pAudioBufferRef->channels;
*pSampleRate = 0; /* There is no notion of a sample rate with audio buffers. */ *pSampleRate = 0; /* There is no notion of a sample rate with audio buffers. */
ma_get_standard_channel_map(ma_standard_channel_map_default, (ma_uint32)ma_min(pAudioBufferRef->channels, channelMapCap), pChannelMap);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -46676,19 +46684,11 @@ static ma_result ma_decoder__init_data_converter(ma_decoder* pDecoder, const ma_ ...@@ -46676,19 +46684,11 @@ static ma_result ma_decoder__init_data_converter(ma_decoder* pDecoder, const ma_
MA_ASSERT(pDecoder != NULL); MA_ASSERT(pDecoder != NULL);
MA_ASSERT(pConfig != NULL); MA_ASSERT(pConfig != NULL);
result = ma_data_source_get_data_format(pDecoder->pBackend, &internalFormat, &internalChannels, &internalSampleRate); result = ma_data_source_get_data_format(pDecoder->pBackend, &internalFormat, &internalChannels, &internalSampleRate, internalChannelMap, ma_countof(internalChannelMap));
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the internal data format. */ return result; /* Failed to retrieve the internal data format. */
} }
/* Channel map needs to be retrieved separately. */
if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onGetChannelMap != NULL) {
pDecoder->pBackendVTable->onGetChannelMap(pDecoder->pBackendUserData, pDecoder->pBackend, internalChannelMap, ma_countof(internalChannelMap));
} else {
ma_get_standard_channel_map(ma_standard_channel_map_default, ma_min(internalChannels, ma_countof(internalChannelMap)), internalChannelMap);
}
/* Make sure we're not asking for too many channels. */ /* Make sure we're not asking for too many channels. */
if (pConfig->channels > MA_MAX_CHANNELS) { if (pConfig->channels > MA_MAX_CHANNELS) {
...@@ -46877,9 +46877,9 @@ static ma_result ma_wav_ds_seek(ma_data_source* pDataSource, ma_uint64 frameInde ...@@ -46877,9 +46877,9 @@ static ma_result ma_wav_ds_seek(ma_data_source* pDataSource, ma_uint64 frameInde
return ma_wav_seek_to_pcm_frame((ma_wav*)pDataSource, frameIndex); return ma_wav_seek_to_pcm_frame((ma_wav*)pDataSource, frameIndex);
} }
static ma_result ma_wav_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_wav_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_wav_get_data_format((ma_wav*)pDataSource, pFormat, pChannels, pSampleRate, NULL, 0); return ma_wav_get_data_format((ma_wav*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_wav_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_wav_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
...@@ -47452,23 +47452,13 @@ static void ma_decoding_backend_uninit__wav(void* pUserData, ma_data_source* pBa ...@@ -47452,23 +47452,13 @@ static void ma_decoding_backend_uninit__wav(void* pUserData, ma_data_source* pBa
ma_free(pWav, pAllocationCallbacks); ma_free(pWav, pAllocationCallbacks);
} }
static ma_result ma_decoding_backend_get_channel_map__wav(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap)
{
ma_wav* pWav = (ma_wav*)pBackend;
(void)pUserData;
return ma_wav_get_data_format(pWav, NULL, NULL, NULL, pChannelMap, channelMapCap);
}
static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_wav = static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_wav =
{ {
ma_decoding_backend_init__wav, ma_decoding_backend_init__wav,
ma_decoding_backend_init_file__wav, ma_decoding_backend_init_file__wav,
ma_decoding_backend_init_file_w__wav, ma_decoding_backend_init_file_w__wav,
ma_decoding_backend_init_memory__wav, ma_decoding_backend_init_memory__wav,
ma_decoding_backend_uninit__wav, ma_decoding_backend_uninit__wav
ma_decoding_backend_get_channel_map__wav
}; };
static ma_result ma_decoder_init_wav__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder_init_wav__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
...@@ -47516,9 +47506,9 @@ static ma_result ma_flac_ds_seek(ma_data_source* pDataSource, ma_uint64 frameInd ...@@ -47516,9 +47506,9 @@ static ma_result ma_flac_ds_seek(ma_data_source* pDataSource, ma_uint64 frameInd
return ma_flac_seek_to_pcm_frame((ma_flac*)pDataSource, frameIndex); return ma_flac_seek_to_pcm_frame((ma_flac*)pDataSource, frameIndex);
} }
static ma_result ma_flac_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_flac_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_flac_get_data_format((ma_flac*)pDataSource, pFormat, pChannels, pSampleRate, NULL, 0); return ma_flac_get_data_format((ma_flac*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_flac_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_flac_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
...@@ -48082,23 +48072,13 @@ static void ma_decoding_backend_uninit__flac(void* pUserData, ma_data_source* pB ...@@ -48082,23 +48072,13 @@ static void ma_decoding_backend_uninit__flac(void* pUserData, ma_data_source* pB
ma_free(pFlac, pAllocationCallbacks); ma_free(pFlac, pAllocationCallbacks);
} }
static ma_result ma_decoding_backend_get_channel_map__flac(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap)
{
ma_flac* pFlac = (ma_flac*)pBackend;
(void)pUserData;
return ma_flac_get_data_format(pFlac, NULL, NULL, NULL, pChannelMap, channelMapCap);
}
static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_flac = static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_flac =
{ {
ma_decoding_backend_init__flac, ma_decoding_backend_init__flac,
ma_decoding_backend_init_file__flac, ma_decoding_backend_init_file__flac,
ma_decoding_backend_init_file_w__flac, ma_decoding_backend_init_file_w__flac,
ma_decoding_backend_init_memory__flac, ma_decoding_backend_init_memory__flac,
ma_decoding_backend_uninit__flac, ma_decoding_backend_uninit__flac
ma_decoding_backend_get_channel_map__flac
}; };
static ma_result ma_decoder_init_flac__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder_init_flac__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
...@@ -48146,9 +48126,9 @@ static ma_result ma_mp3_ds_seek(ma_data_source* pDataSource, ma_uint64 frameInde ...@@ -48146,9 +48126,9 @@ static ma_result ma_mp3_ds_seek(ma_data_source* pDataSource, ma_uint64 frameInde
return ma_mp3_seek_to_pcm_frame((ma_mp3*)pDataSource, frameIndex); return ma_mp3_seek_to_pcm_frame((ma_mp3*)pDataSource, frameIndex);
} }
static ma_result ma_mp3_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_mp3_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_mp3_get_data_format((ma_mp3*)pDataSource, pFormat, pChannels, pSampleRate, NULL, 0); return ma_mp3_get_data_format((ma_mp3*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_mp3_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_mp3_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
...@@ -48712,23 +48692,13 @@ static void ma_decoding_backend_uninit__mp3(void* pUserData, ma_data_source* pBa ...@@ -48712,23 +48692,13 @@ static void ma_decoding_backend_uninit__mp3(void* pUserData, ma_data_source* pBa
ma_free(pMP3, pAllocationCallbacks); ma_free(pMP3, pAllocationCallbacks);
} }
static ma_result ma_decoding_backend_get_channel_map__mp3(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap)
{
ma_mp3* pMP3 = (ma_mp3*)pBackend;
(void)pUserData;
return ma_mp3_get_data_format(pMP3, NULL, NULL, NULL, pChannelMap, channelMapCap);
}
static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_mp3 = static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_mp3 =
{ {
ma_decoding_backend_init__mp3, ma_decoding_backend_init__mp3,
ma_decoding_backend_init_file__mp3, ma_decoding_backend_init_file__mp3,
ma_decoding_backend_init_file_w__mp3, ma_decoding_backend_init_file_w__mp3,
ma_decoding_backend_init_memory__mp3, ma_decoding_backend_init_memory__mp3,
ma_decoding_backend_uninit__mp3, ma_decoding_backend_uninit__mp3
ma_decoding_backend_get_channel_map__mp3
}; };
static ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
...@@ -48792,9 +48762,9 @@ static ma_result ma_stbvorbis_ds_seek(ma_data_source* pDataSource, ma_uint64 fra ...@@ -48792,9 +48762,9 @@ static ma_result ma_stbvorbis_ds_seek(ma_data_source* pDataSource, ma_uint64 fra
return ma_stbvorbis_seek_to_pcm_frame((ma_stbvorbis*)pDataSource, frameIndex); return ma_stbvorbis_seek_to_pcm_frame((ma_stbvorbis*)pDataSource, frameIndex);
} }
static ma_result ma_stbvorbis_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_stbvorbis_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_stbvorbis_get_data_format((ma_stbvorbis*)pDataSource, pFormat, pChannels, pSampleRate, NULL, 0); return ma_stbvorbis_get_data_format((ma_stbvorbis*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_stbvorbis_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_stbvorbis_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
...@@ -49496,23 +49466,13 @@ static void ma_decoding_backend_uninit__stbvorbis(void* pUserData, ma_data_sourc ...@@ -49496,23 +49466,13 @@ static void ma_decoding_backend_uninit__stbvorbis(void* pUserData, ma_data_sourc
ma_free(pVorbis, pAllocationCallbacks); ma_free(pVorbis, pAllocationCallbacks);
} }
static ma_result ma_decoding_backend_get_channel_map__stbvorbis(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap)
{
ma_stbvorbis* pVorbis = (ma_stbvorbis*)pBackend;
(void)pUserData;
return ma_stbvorbis_get_data_format(pVorbis, NULL, NULL, NULL, pChannelMap, channelMapCap);
}
static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_stbvorbis = static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_stbvorbis =
{ {
ma_decoding_backend_init__stbvorbis, ma_decoding_backend_init__stbvorbis,
ma_decoding_backend_init_file__stbvorbis, ma_decoding_backend_init_file__stbvorbis,
NULL, /* onInitFileW() */ NULL, /* onInitFileW() */
ma_decoding_backend_init_memory__stbvorbis, ma_decoding_backend_init_memory__stbvorbis,
ma_decoding_backend_uninit__stbvorbis, ma_decoding_backend_uninit__stbvorbis
ma_decoding_backend_get_channel_map__stbvorbis
}; };
static ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
...@@ -49545,9 +49505,9 @@ static ma_result ma_decoder__data_source_on_seek(ma_data_source* pDataSource, ma ...@@ -49545,9 +49505,9 @@ static ma_result ma_decoder__data_source_on_seek(ma_data_source* pDataSource, ma
return ma_decoder_seek_to_pcm_frame((ma_decoder*)pDataSource, frameIndex); return ma_decoder_seek_to_pcm_frame((ma_decoder*)pDataSource, frameIndex);
} }
static ma_result ma_decoder__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_decoder__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_decoder_get_data_format((ma_decoder*)pDataSource, pFormat, pChannels, pSampleRate, NULL, 0); return ma_decoder_get_data_format((ma_decoder*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_decoder__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_decoder__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
...@@ -49616,7 +49576,7 @@ static ma_result ma_decoder__postinit(const ma_decoder_config* pConfig, ma_decod ...@@ -49616,7 +49576,7 @@ static ma_result ma_decoder__postinit(const ma_decoder_config* pConfig, ma_decod
{ {
/* TODO: Remove this block once we remove MA_MIN_CHANNELS and MA_MAX_CHANNELS. */ /* TODO: Remove this block once we remove MA_MIN_CHANNELS and MA_MAX_CHANNELS. */
ma_uint32 internalChannels; ma_uint32 internalChannels;
ma_data_source_get_data_format(pDecoder->pBackend, NULL, &internalChannels, NULL); ma_data_source_get_data_format(pDecoder->pBackend, NULL, &internalChannels, NULL, NULL, 0);
if (internalChannels < MA_MIN_CHANNELS || internalChannels > MA_MAX_CHANNELS) { if (internalChannels < MA_MIN_CHANNELS || internalChannels > MA_MAX_CHANNELS) {
result = MA_INVALID_DATA; result = MA_INVALID_DATA;
...@@ -50363,7 +50323,7 @@ MA_API ma_result ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesO ...@@ -50363,7 +50323,7 @@ MA_API ma_result ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesO
totalFramesReadIn = 0; totalFramesReadIn = 0;
pRunningFramesOut = pFramesOut; pRunningFramesOut = pFramesOut;
result = ma_data_source_get_data_format(pDecoder->pBackend, &internalFormat, &internalChannels, NULL); result = ma_data_source_get_data_format(pDecoder->pBackend, &internalFormat, &internalChannels, NULL, NULL, 0);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the internal format and channel count. */ return result; /* Failed to retrieve the internal format and channel count. */
} }
...@@ -50438,7 +50398,7 @@ MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 fr ...@@ -50438,7 +50398,7 @@ MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 fr
ma_uint64 internalFrameIndex; ma_uint64 internalFrameIndex;
ma_uint32 internalSampleRate; ma_uint32 internalSampleRate;
result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate); result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate, NULL, 0);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the internal sample rate. */ return result; /* Failed to retrieve the internal sample rate. */
} }
...@@ -50525,7 +50485,7 @@ MA_API ma_result ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder, ma_ui ...@@ -50525,7 +50485,7 @@ MA_API ma_result ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder, ma_ui
return result; /* Failed to retrieve the internal length. */ return result; /* Failed to retrieve the internal length. */
} }
result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate); result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate, NULL, 0);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the internal sample rate. */ return result; /* Failed to retrieve the internal sample rate. */
} }
...@@ -51014,13 +50974,14 @@ static ma_result ma_waveform__data_source_on_seek(ma_data_source* pDataSource, m ...@@ -51014,13 +50974,14 @@ static ma_result ma_waveform__data_source_on_seek(ma_data_source* pDataSource, m
return ma_waveform_seek_to_pcm_frame((ma_waveform*)pDataSource, frameIndex); return ma_waveform_seek_to_pcm_frame((ma_waveform*)pDataSource, frameIndex);
} }
static ma_result ma_waveform__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_waveform__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
ma_waveform* pWaveform = (ma_waveform*)pDataSource; ma_waveform* pWaveform = (ma_waveform*)pDataSource;
*pFormat = pWaveform->config.format; *pFormat = pWaveform->config.format;
*pChannels = pWaveform->config.channels; *pChannels = pWaveform->config.channels;
*pSampleRate = pWaveform->config.sampleRate; *pSampleRate = pWaveform->config.sampleRate;
ma_get_standard_channel_map(ma_standard_channel_map_default, (ma_uint32)ma_min(channelMapCap, pWaveform->config.channels), pChannelMap);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -51451,13 +51412,14 @@ static ma_result ma_noise__data_source_on_seek(ma_data_source* pDataSource, ma_u ...@@ -51451,13 +51412,14 @@ static ma_result ma_noise__data_source_on_seek(ma_data_source* pDataSource, ma_u
return MA_SUCCESS; return MA_SUCCESS;
} }
static ma_result ma_noise__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_noise__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
ma_noise* pNoise = (ma_noise*)pDataSource; ma_noise* pNoise = (ma_noise*)pDataSource;
*pFormat = pNoise->config.format; *pFormat = pNoise->config.format;
*pChannels = pNoise->config.channels; *pChannels = pNoise->config.channels;
*pSampleRate = 0; /* There is no notion of sample rate with noise generation. */ *pSampleRate = 0; /* There is no notion of sample rate with noise generation. */
ma_get_standard_channel_map(ma_standard_channel_map_default, (ma_uint32)ma_min(channelMapCap, pNoise->config.channels), pChannelMap);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -96,8 +96,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libvorbis = ...@@ -96,8 +96,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libvorbis =
ma_decoding_backend_init_file__libvorbis, ma_decoding_backend_init_file__libvorbis,
NULL, /* onInitFileW() */ NULL, /* onInitFileW() */
NULL, /* onInitMemory() */ NULL, /* onInitMemory() */
ma_decoding_backend_uninit__libvorbis, ma_decoding_backend_uninit__libvorbis
ma_decoding_backend_get_channel_map__libvorbis
}; };
...@@ -173,8 +172,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libopus = ...@@ -173,8 +172,7 @@ static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libopus =
ma_decoding_backend_init_file__libopus, ma_decoding_backend_init_file__libopus,
NULL, /* onInitFileW() */ NULL, /* onInitFileW() */
NULL, /* onInitMemory() */ NULL, /* onInitMemory() */
ma_decoding_backend_uninit__libopus, ma_decoding_backend_uninit__libopus
ma_decoding_backend_get_channel_map__libopus
}; };
......
...@@ -73,7 +73,7 @@ MA_API ma_result ma_data_source_read_pcm_frames_f32(ma_data_source* pDataSource, ...@@ -73,7 +73,7 @@ MA_API ma_result ma_data_source_read_pcm_frames_f32(ma_data_source* pDataSource,
ma_format format; ma_format format;
ma_uint32 channels; ma_uint32 channels;
result = ma_data_source_get_data_format(pDataSource, &format, &channels, NULL); result = ma_data_source_get_data_format(pDataSource, &format, &channels, NULL, NULL, 0);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the data format of the data source. */ return result; /* Failed to retrieve the data format of the data source. */
} }
...@@ -96,7 +96,7 @@ MA_API ma_result ma_data_source_read_pcm_frames_and_mix_f32(ma_data_source* pDat ...@@ -96,7 +96,7 @@ MA_API ma_result ma_data_source_read_pcm_frames_and_mix_f32(ma_data_source* pDat
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
result = ma_data_source_get_data_format(pDataSource, &format, &channels, NULL); result = ma_data_source_get_data_format(pDataSource, &format, &channels, NULL, NULL, 0);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the data format of the data source. */ return result; /* Failed to retrieve the data format of the data source. */
} }
......
...@@ -1541,7 +1541,7 @@ MA_API ma_result ma_resource_manager_data_buffer_init_copy(ma_resource_manager* ...@@ -1541,7 +1541,7 @@ MA_API ma_result ma_resource_manager_data_buffer_init_copy(ma_resource_manager*
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_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_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); MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate); MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor); MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor);
MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength); MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength);
MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer); MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer);
...@@ -1555,7 +1555,7 @@ MA_API ma_result ma_resource_manager_data_stream_init_w(ma_resource_manager* pRe ...@@ -1555,7 +1555,7 @@ MA_API ma_result ma_resource_manager_data_stream_init_w(ma_resource_manager* pRe
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_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_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); MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameIndex);
MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate); MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor); MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor);
MA_API ma_result ma_resource_manager_data_stream_get_length_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pLength); MA_API ma_result ma_resource_manager_data_stream_get_length_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pLength);
MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream); MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream);
...@@ -1570,7 +1570,7 @@ MA_API ma_result ma_resource_manager_data_source_init_copy(ma_resource_manager* ...@@ -1570,7 +1570,7 @@ MA_API ma_result ma_resource_manager_data_source_init_copy(ma_resource_manager*
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_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_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); MA_API ma_result ma_resource_manager_data_source_seek_to_pcm_frame(ma_resource_manager_data_source* pDataSource, ma_uint64 frameIndex);
MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate); MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_resource_manager_data_source_get_cursor_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pCursor); MA_API ma_result ma_resource_manager_data_source_get_cursor_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pCursor);
MA_API ma_result ma_resource_manager_data_source_get_length_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pLength); MA_API ma_result ma_resource_manager_data_source_get_length_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pLength);
MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource); MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource);
...@@ -2048,7 +2048,7 @@ MA_API void ma_sound_set_looping(ma_sound* pSound, ma_bool8 isLooping); ...@@ -2048,7 +2048,7 @@ MA_API void ma_sound_set_looping(ma_sound* pSound, ma_bool8 isLooping);
MA_API ma_bool32 ma_sound_is_looping(const ma_sound* pSound); MA_API ma_bool32 ma_sound_is_looping(const ma_sound* pSound);
MA_API ma_bool32 ma_sound_at_end(const ma_sound* pSound); MA_API ma_bool32 ma_sound_at_end(const ma_sound* pSound);
MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameIndex); /* Just a wrapper around ma_data_source_seek_to_pcm_frame(). */ MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameIndex); /* Just a wrapper around ma_data_source_seek_to_pcm_frame(). */
MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate); MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor); MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor);
MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength); MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength);
...@@ -2537,13 +2537,14 @@ static ma_result ma_paged_audio_buffer__data_source_on_seek(ma_data_source* pDat ...@@ -2537,13 +2537,14 @@ static ma_result ma_paged_audio_buffer__data_source_on_seek(ma_data_source* pDat
return ma_paged_audio_buffer_seek_to_pcm_frame((ma_paged_audio_buffer*)pDataSource, frameIndex); return ma_paged_audio_buffer_seek_to_pcm_frame((ma_paged_audio_buffer*)pDataSource, frameIndex);
} }
static ma_result ma_paged_audio_buffer__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_paged_audio_buffer__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
ma_paged_audio_buffer* pPagedAudioBuffer = (ma_paged_audio_buffer*)pDataSource; ma_paged_audio_buffer* pPagedAudioBuffer = (ma_paged_audio_buffer*)pDataSource;
*pFormat = pPagedAudioBuffer->pData->format; *pFormat = pPagedAudioBuffer->pData->format;
*pChannels = pPagedAudioBuffer->pData->channels; *pChannels = pPagedAudioBuffer->pData->channels;
*pSampleRate = 0; /* There is no notion of a sample rate with audio buffers. */ *pSampleRate = 0; /* There is no notion of a sample rate with audio buffers. */
ma_get_standard_channel_map(ma_standard_channel_map_default, (ma_uint32)ma_min(channelMapCap, pPagedAudioBuffer->pData->channels), pChannelMap);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -5268,7 +5269,7 @@ static void ma_data_source_node_process_pcm_frames(ma_node* pNode, const float** ...@@ -5268,7 +5269,7 @@ static void ma_data_source_node_process_pcm_frames(ma_node* pNode, const float**
frameCount = *pFrameCountOut; frameCount = *pFrameCountOut;
if (ma_data_source_get_data_format(pDataSourceNode->pDataSource, &format, &channels, NULL) == MA_SUCCESS) { /* <-- Don't care about sample rate here. */ if (ma_data_source_get_data_format(pDataSourceNode->pDataSource, &format, &channels, NULL, NULL, 0) == MA_SUCCESS) { /* <-- Don't care about sample rate here. */
/* The node graph system requires samples be in floating point format. This is checked in ma_data_source_node_init(). */ /* The node graph system requires samples be in floating point format. This is checked in ma_data_source_node_init(). */
MA_ASSERT(format == ma_format_f32); MA_ASSERT(format == ma_format_f32);
(void)format; /* Just to silence some static analysis tools. */ (void)format; /* Just to silence some static analysis tools. */
...@@ -5305,7 +5306,7 @@ MA_API ma_result ma_data_source_node_init(ma_node_graph* pNodeGraph, const ma_da ...@@ -5305,7 +5306,7 @@ MA_API ma_result ma_data_source_node_init(ma_node_graph* pNodeGraph, const ma_da
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
result = ma_data_source_get_data_format(pConfig->pDataSource, &format, &channels, NULL); /* Don't care about sample rate. This will check pDataSource for NULL. */ result = ma_data_source_get_data_format(pConfig->pDataSource, &format, &channels, NULL, NULL, 0); /* Don't care about sample rate. This will check pDataSource for NULL. */
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; return result;
} }
...@@ -8254,9 +8255,9 @@ static ma_result ma_resource_manager_data_buffer_cb__seek_to_pcm_frame(ma_data_s ...@@ -8254,9 +8255,9 @@ static ma_result ma_resource_manager_data_buffer_cb__seek_to_pcm_frame(ma_data_s
return ma_resource_manager_data_buffer_seek_to_pcm_frame((ma_resource_manager_data_buffer*)pDataSource, frameIndex); return ma_resource_manager_data_buffer_seek_to_pcm_frame((ma_resource_manager_data_buffer*)pDataSource, frameIndex);
} }
static ma_result ma_resource_manager_data_buffer_cb__get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_resource_manager_data_buffer_cb__get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_resource_manager_data_buffer_get_data_format((ma_resource_manager_data_buffer*)pDataSource, pFormat, pChannels, pSampleRate); return ma_resource_manager_data_buffer_get_data_format((ma_resource_manager_data_buffer*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_resource_manager_data_buffer_cb__get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_resource_manager_data_buffer_cb__get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor)
...@@ -8624,7 +8625,7 @@ MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_m ...@@ -8624,7 +8625,7 @@ MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_m
return MA_SUCCESS; return MA_SUCCESS;
} }
MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
/* We cannot be using the data source after it's been uninitialized. */ /* We cannot be using the data source after it's been uninitialized. */
MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE);
...@@ -8633,7 +8634,7 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man ...@@ -8633,7 +8634,7 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man
{ {
case ma_resource_manager_data_supply_type_encoded: case ma_resource_manager_data_supply_type_encoded:
{ {
return ma_data_source_get_data_format(&pDataBuffer->connector.decoder, pFormat, pChannels, pSampleRate); return ma_data_source_get_data_format(&pDataBuffer->connector.decoder, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}; };
case ma_resource_manager_data_supply_type_decoded: case ma_resource_manager_data_supply_type_decoded:
...@@ -8641,6 +8642,7 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man ...@@ -8641,6 +8642,7 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man
*pFormat = pDataBuffer->pNode->data.decoded.format; *pFormat = pDataBuffer->pNode->data.decoded.format;
*pChannels = pDataBuffer->pNode->data.decoded.channels; *pChannels = pDataBuffer->pNode->data.decoded.channels;
*pSampleRate = pDataBuffer->pNode->data.decoded.sampleRate; *pSampleRate = pDataBuffer->pNode->data.decoded.sampleRate;
ma_get_standard_channel_map(ma_standard_channel_map_default, (ma_uint32)ma_min(channelMapCap, pDataBuffer->pNode->data.decoded.channels), pChannelMap);
return MA_SUCCESS; return MA_SUCCESS;
}; };
...@@ -8649,6 +8651,7 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man ...@@ -8649,6 +8651,7 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man
*pFormat = pDataBuffer->pNode->data.decodedPaged.data.format; *pFormat = pDataBuffer->pNode->data.decodedPaged.data.format;
*pChannels = pDataBuffer->pNode->data.decodedPaged.data.channels; *pChannels = pDataBuffer->pNode->data.decodedPaged.data.channels;
*pSampleRate = pDataBuffer->pNode->data.decodedPaged.sampleRate; *pSampleRate = pDataBuffer->pNode->data.decodedPaged.sampleRate;
ma_get_standard_channel_map(ma_standard_channel_map_default, (ma_uint32)ma_min(channelMapCap, pDataBuffer->pNode->data.decoded.channels), pChannelMap);
return MA_SUCCESS; return MA_SUCCESS;
}; };
...@@ -8924,9 +8927,9 @@ static ma_result ma_resource_manager_data_stream_cb__seek_to_pcm_frame(ma_data_s ...@@ -8924,9 +8927,9 @@ static ma_result ma_resource_manager_data_stream_cb__seek_to_pcm_frame(ma_data_s
return ma_resource_manager_data_stream_seek_to_pcm_frame((ma_resource_manager_data_stream*)pDataSource, frameIndex); return ma_resource_manager_data_stream_seek_to_pcm_frame((ma_resource_manager_data_stream*)pDataSource, frameIndex);
} }
static ma_result ma_resource_manager_data_stream_cb__get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_resource_manager_data_stream_cb__get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
return ma_resource_manager_data_stream_get_data_format((ma_resource_manager_data_stream*)pDataSource, pFormat, pChannels, pSampleRate); return ma_resource_manager_data_stream_get_data_format((ma_resource_manager_data_stream*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
static ma_result ma_resource_manager_data_stream_cb__get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_resource_manager_data_stream_cb__get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor)
...@@ -9327,7 +9330,7 @@ MA_API ma_result ma_resource_manager_data_stream_read_pcm_frames(ma_resource_man ...@@ -9327,7 +9330,7 @@ MA_API ma_result ma_resource_manager_data_stream_read_pcm_frames(ma_resource_man
return MA_BUSY; return MA_BUSY;
} }
ma_resource_manager_data_stream_get_data_format(pDataStream, &format, &channels, NULL); ma_resource_manager_data_stream_get_data_format(pDataStream, &format, &channels, NULL, NULL, 0);
/* Reading is implemented in terms of map/unmap. We need to run this in a loop because mapping is clamped against page boundaries. */ /* Reading is implemented in terms of map/unmap. We need to run this in a loop because mapping is clamped against page boundaries. */
totalFramesProcessed = 0; totalFramesProcessed = 0;
...@@ -9409,7 +9412,7 @@ MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_m ...@@ -9409,7 +9412,7 @@ MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_m
return ma_resource_manager_post_job(pDataStream->pResourceManager, &job); return ma_resource_manager_post_job(pDataStream->pResourceManager, &job);
} }
MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
/* We cannot be using the data source after it's been uninitialized. */ /* We cannot be using the data source after it's been uninitialized. */
MA_ASSERT(ma_resource_manager_data_stream_result(pDataStream) != MA_UNAVAILABLE); MA_ASSERT(ma_resource_manager_data_stream_result(pDataStream) != MA_UNAVAILABLE);
...@@ -9426,6 +9429,10 @@ MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_man ...@@ -9426,6 +9429,10 @@ MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_man
*pSampleRate = 0; *pSampleRate = 0;
} }
if (pChannelMap != NULL) {
MA_ZERO_MEMORY(pChannelMap, sizeof(*pChannelMap) * channelMapCap);
}
if (pDataStream == NULL) { if (pDataStream == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
...@@ -9438,7 +9445,7 @@ MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_man ...@@ -9438,7 +9445,7 @@ MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_man
We're being a little bit naughty here and accessing the internal decoder from the public API. The output data format is constant, and we've defined this function We're being a little bit naughty here and accessing the internal decoder from the public API. The output data format is constant, and we've defined this function
such that the application is responsible for ensuring it's not called while uninitializing so it should be safe. such that the application is responsible for ensuring it's not called while uninitializing so it should be safe.
*/ */
return ma_data_source_get_data_format(&pDataStream->decoder, pFormat, pChannels, pSampleRate); return ma_data_source_get_data_format(&pDataStream->decoder, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor) MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor)
...@@ -9714,16 +9721,16 @@ MA_API ma_result ma_resource_manager_data_source_unmap(ma_resource_manager_data_ ...@@ -9714,16 +9721,16 @@ MA_API ma_result ma_resource_manager_data_source_unmap(ma_resource_manager_data_
} }
} }
MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
if (pDataSource == NULL) { if (pDataSource == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
if ((pDataSource->flags & MA_DATA_SOURCE_FLAG_STREAM) != 0) { if ((pDataSource->flags & MA_DATA_SOURCE_FLAG_STREAM) != 0) {
return ma_resource_manager_data_stream_get_data_format(&pDataSource->stream, pFormat, pChannels, pSampleRate); return ma_resource_manager_data_stream_get_data_format(&pDataSource->stream, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} else { } else {
return ma_resource_manager_data_buffer_get_data_format(&pDataSource->buffer, pFormat, pChannels, pSampleRate); return ma_resource_manager_data_buffer_get_data_format(&pDataSource->buffer, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
} }
...@@ -12389,7 +12396,7 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float ...@@ -12389,7 +12396,7 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float
For the convenience of the caller, we're doing to allow data sources to use non-floating-point formats and channel counts that differ For the convenience of the caller, we're doing to allow data sources to use non-floating-point formats and channel counts that differ
from the main engine. from the main engine.
*/ */
result = ma_data_source_get_data_format(pSound->pDataSource, &dataSourceFormat, &dataSourceChannels, NULL); result = ma_data_source_get_data_format(pSound->pDataSource, &dataSourceFormat, &dataSourceChannels, NULL, NULL, 0);
if (result == MA_SUCCESS) { if (result == MA_SUCCESS) {
tempCapInFrames = sizeof(temp) / ma_get_bytes_per_frame(dataSourceFormat, dataSourceChannels); tempCapInFrames = sizeof(temp) / ma_get_bytes_per_frame(dataSourceFormat, dataSourceChannels);
...@@ -13498,7 +13505,7 @@ static ma_result ma_sound_init_from_data_source_internal(ma_engine* pEngine, con ...@@ -13498,7 +13505,7 @@ static ma_result ma_sound_init_from_data_source_internal(ma_engine* pEngine, con
/* If we're loading from a data source the input channel count needs to be the data source's native channel count. */ /* If we're loading from a data source the input channel count needs to be the data source's native channel count. */
if (pConfig->pDataSource != NULL) { if (pConfig->pDataSource != NULL) {
result = ma_data_source_get_data_format(pConfig->pDataSource, NULL, &engineNodeConfig.channelsIn, &engineNodeConfig.sampleRate); result = ma_data_source_get_data_format(pConfig->pDataSource, NULL, &engineNodeConfig.channelsIn, &engineNodeConfig.sampleRate, NULL, 0);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the channel count. */ return result; /* Failed to retrieve the channel count. */
} }
...@@ -14255,7 +14262,7 @@ MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameInd ...@@ -14255,7 +14262,7 @@ MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameInd
return MA_SUCCESS; return MA_SUCCESS;
} }
MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{ {
if (pSound == NULL) { if (pSound == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
...@@ -14263,21 +14270,28 @@ MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ...@@ -14263,21 +14270,28 @@ MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat,
/* The data format is retrieved directly from the data source if the sound is backed by one. Otherwise we pull it from the node. */ /* The data format is retrieved directly from the data source if the sound is backed by one. Otherwise we pull it from the node. */
if (pSound->pDataSource == NULL) { if (pSound->pDataSource == NULL) {
ma_uint32 channels;
if (pFormat != NULL) { if (pFormat != NULL) {
*pFormat = ma_format_f32; *pFormat = ma_format_f32;
} }
channels = ma_node_get_input_channels(&pSound->engineNode, 0);
if (pChannels != NULL) { if (pChannels != NULL) {
*pChannels = ma_node_get_input_channels(&pSound->engineNode, 0); *pChannels = channels;
} }
if (pSampleRate != NULL) { if (pSampleRate != NULL) {
*pSampleRate = pSound->engineNode.resampler.config.sampleRateIn; *pSampleRate = pSound->engineNode.resampler.config.sampleRateIn;
} }
if (pChannelMap != NULL) {
ma_get_standard_channel_map(ma_standard_channel_map_default, (ma_uint32)ma_min(channels, channelMapCap), pChannelMap);
}
return MA_SUCCESS; return MA_SUCCESS;
} else { } else {
return ma_data_source_get_data_format(pSound->pDataSource, pFormat, pChannels, pSampleRate); return ma_data_source_get_data_format(pSound->pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
} }
} }
......
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