mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-21 15:56:58 +02:00
Channel Converter: Stop doing a micro heap allocation.
With small channel counts, mono and stereo, the channel converter will no longer allocate memory on the heap for the channel map, but will instead just store it in the struct directly. For larger channel counts it will fall back to a heap allocation. This prevents stereo channel maps resulting in a heap allocation of 8 bytes. With this change a stereo passthrough `ma_device` can be initialized with a heap allocation for the internal data converter. This only affects passthrough channel conversion. When shuffling or weights are required, a heap allocation will still be done. This optimization is specifically for passthrough.
This commit is contained in:
+25
-5
@@ -5819,6 +5819,10 @@ MA_API ma_channel_converter_config ma_channel_converter_config_init(ma_format fo
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Memory management. */
|
||||
void* _pHeap;
|
||||
ma_bool32 _ownsHeap;
|
||||
|
||||
ma_format format;
|
||||
ma_uint32 channelsIn;
|
||||
ma_uint32 channelsOut;
|
||||
@@ -5833,9 +5837,13 @@ typedef struct
|
||||
ma_int32** s16;
|
||||
} weights; /* [in][out] */
|
||||
|
||||
/* Memory management. */
|
||||
void* _pHeap;
|
||||
ma_bool32 _ownsHeap;
|
||||
/*
|
||||
In order to avoid micro heap allocations for the channel map when using a small channel count,
|
||||
we will have a small local array here for the in and out channel maps. If the channel count
|
||||
exceeds the capacity of these channel maps it'll fall back to the heap.
|
||||
*/
|
||||
ma_channel _smallChannelMapIn[2];
|
||||
ma_channel _smallChannelMapOut[2];
|
||||
} ma_channel_converter;
|
||||
|
||||
MA_API ma_result ma_channel_converter_get_heap_size(const ma_channel_converter_config* pConfig, size_t* pHeapSizeInBytes);
|
||||
@@ -63128,17 +63136,19 @@ static ma_result ma_channel_converter_get_heap_layout(const ma_channel_converter
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
MA_ZERO_OBJECT(pHeapLayout);
|
||||
|
||||
pHeapLayout->sizeInBytes = 0;
|
||||
|
||||
/* Input channel map. Only need to allocate this if we have an input channel map (otherwise default channel map is assumed). */
|
||||
pHeapLayout->channelMapInOffset = pHeapLayout->sizeInBytes;
|
||||
if (pConfig->pChannelMapIn != NULL) {
|
||||
if (pConfig->pChannelMapIn != NULL && pConfig->channelsIn > ma_countof(((ma_channel_converter*)0)->_smallChannelMapIn)) {
|
||||
pHeapLayout->sizeInBytes += sizeof(ma_channel) * pConfig->channelsIn;
|
||||
}
|
||||
|
||||
/* Output channel map. Only need to allocate this if we have an output channel map (otherwise default channel map is assumed). */
|
||||
pHeapLayout->channelMapOutOffset = pHeapLayout->sizeInBytes;
|
||||
if (pConfig->pChannelMapOut != NULL) {
|
||||
if (pConfig->pChannelMapOut != NULL && pConfig->channelsOut > ma_countof(((ma_channel_converter*)0)->_smallChannelMapOut)) {
|
||||
pHeapLayout->sizeInBytes += sizeof(ma_channel) * pConfig->channelsOut;
|
||||
}
|
||||
|
||||
@@ -63213,14 +63223,24 @@ MA_API ma_result ma_channel_converter_init_preallocated(const ma_channel_convert
|
||||
pConverter->mixingMode = pConfig->mixingMode;
|
||||
|
||||
if (pConfig->pChannelMapIn != NULL) {
|
||||
if (pConfig->channelsIn > ma_countof(pConverter->_smallChannelMapIn)) {
|
||||
pConverter->pChannelMapIn = (ma_channel*)ma_offset_ptr(pHeap, heapLayout.channelMapInOffset);
|
||||
} else {
|
||||
pConverter->pChannelMapIn = pConverter->_smallChannelMapIn;
|
||||
}
|
||||
|
||||
ma_channel_map_copy_or_default(pConverter->pChannelMapIn, pConfig->channelsIn, pConfig->pChannelMapIn, pConfig->channelsIn);
|
||||
} else {
|
||||
pConverter->pChannelMapIn = NULL; /* Use default channel map. */
|
||||
}
|
||||
|
||||
if (pConfig->pChannelMapOut != NULL) {
|
||||
if (pConfig->channelsOut > ma_countof(pConverter->_smallChannelMapOut)) {
|
||||
pConverter->pChannelMapOut = (ma_channel*)ma_offset_ptr(pHeap, heapLayout.channelMapOutOffset);
|
||||
} else {
|
||||
pConverter->pChannelMapOut = pConverter->_smallChannelMapOut;
|
||||
}
|
||||
|
||||
ma_channel_map_copy_or_default(pConverter->pChannelMapOut, pConfig->channelsOut, pConfig->pChannelMapOut, pConfig->channelsOut);
|
||||
} else {
|
||||
pConverter->pChannelMapOut = NULL; /* Use default channel map. */
|
||||
|
||||
Reference in New Issue
Block a user