mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Clean up.
This commit is contained in:
@@ -17865,9 +17865,6 @@ mal_uint32 mal_src_cache_read_frames_deinterleaved(mal_src_cache* pCache, mal_ui
|
||||
}
|
||||
|
||||
|
||||
//mal_uint64 mal_src_read_frames_passthrough(mal_src* pSRC, mal_uint64 frameCount, void* pFramesOut, mal_bool32 flush, void* pUserData);
|
||||
//mal_uint64 mal_src_read_frames_linear(mal_src* pSRC, mal_uint64 frameCount, void* pFramesOut, mal_bool32 flush, void* pUserData);
|
||||
|
||||
mal_uint64 mal_src_read_deinterleaved__passthrough(mal_src* pSRC, mal_uint64 frameCount, void** ppSamplesOut, mal_bool32 flush, void* pUserData);
|
||||
mal_uint64 mal_src_read_deinterleaved__linear(mal_src* pSRC, mal_uint64 frameCount, void** ppSamplesOut, mal_bool32 flush, void* pUserData);
|
||||
|
||||
@@ -17922,33 +17919,6 @@ mal_result mal_src_set_output_sample_rate(mal_src* pSRC, mal_uint32 sampleRateOu
|
||||
return MAL_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
mal_uint64 mal_src_read(mal_src* pSRC, mal_uint64 frameCount, void* pFramesOut, void* pUserData)
|
||||
{
|
||||
return mal_src_read_ex(pSRC, frameCount, pFramesOut, MAL_FALSE, pUserData);
|
||||
}
|
||||
|
||||
mal_uint64 mal_src_read_ex(mal_src* pSRC, mal_uint64 frameCount, void* pFramesOut, mal_bool32 flush, void* pUserData)
|
||||
{
|
||||
if (pSRC == NULL || frameCount == 0 || pFramesOut == NULL) return 0;
|
||||
|
||||
mal_src_algorithm algorithm = pSRC->config.algorithm;
|
||||
|
||||
// Always use passthrough if the sample rates are the same.
|
||||
if (pSRC->config.sampleRateIn == pSRC->config.sampleRateOut) {
|
||||
algorithm = mal_src_algorithm_none;
|
||||
}
|
||||
|
||||
// Could just use a function pointer instead of a switch for this...
|
||||
switch (algorithm)
|
||||
{
|
||||
case mal_src_algorithm_none: return mal_src_read_frames_passthrough(pSRC, frameCount, pFramesOut, flush, pUserData);
|
||||
case mal_src_algorithm_linear: return mal_src_read_frames_linear(pSRC, frameCount, pFramesOut, flush, pUserData);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mal_uint64 mal_src_read_deinterleaved(mal_src* pSRC, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData)
|
||||
{
|
||||
return mal_src_read_deinterleaved_ex(pSRC, frameCount, ppSamplesOut, MAL_FALSE, pUserData);
|
||||
@@ -17976,120 +17946,6 @@ mal_uint64 mal_src_read_deinterleaved_ex(mal_src* pSRC, mal_uint64 frameCount, v
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
mal_uint64 mal_src_read_frames_passthrough(mal_src* pSRC, mal_uint64 frameCount, void* pFramesOut, mal_bool32 flush, void* pUserData)
|
||||
{
|
||||
mal_assert(pSRC != NULL);
|
||||
mal_assert(frameCount > 0);
|
||||
mal_assert(pFramesOut != NULL);
|
||||
|
||||
(void)flush; // Passthrough need not care about flushing.
|
||||
|
||||
if (frameCount <= UINT32_MAX) {
|
||||
return pSRC->config.onRead(pSRC, (mal_uint32)frameCount, pFramesOut, pUserData);
|
||||
} else {
|
||||
mal_uint64 totalFramesRead = 0;
|
||||
while (frameCount > 0) {
|
||||
mal_uint32 framesToReadRightNow = UINT32_MAX;
|
||||
if (framesToReadRightNow > frameCount) {
|
||||
framesToReadRightNow = (mal_uint32)frameCount;
|
||||
}
|
||||
|
||||
mal_uint32 framesRead = pSRC->config.onRead(pSRC, framesToReadRightNow, pFramesOut, pUserData);
|
||||
if (framesRead == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
pFramesOut = (mal_uint8*)pFramesOut + (framesRead * pSRC->config.channels * sizeof(float));
|
||||
frameCount -= framesRead;
|
||||
totalFramesRead += framesRead;
|
||||
}
|
||||
|
||||
return totalFramesRead;
|
||||
}
|
||||
}
|
||||
|
||||
mal_uint64 mal_src_read_frames_linear(mal_src* pSRC, mal_uint64 frameCount, void* pFramesOut, mal_bool32 flush, void* pUserData)
|
||||
{
|
||||
mal_assert(pSRC != NULL);
|
||||
mal_assert(frameCount > 0);
|
||||
mal_assert(pFramesOut != NULL);
|
||||
|
||||
// For linear SRC, the bin is only 2 frames: 1 prior, 1 future.
|
||||
|
||||
// Load the bin if necessary.
|
||||
if (!pSRC->linear.isPrevFramesLoaded) {
|
||||
mal_uint32 framesRead = mal_src_cache_read_frames(&pSRC->cache, 1, pSRC->bin, pUserData);
|
||||
if (framesRead == 0) {
|
||||
return 0;
|
||||
}
|
||||
pSRC->linear.isPrevFramesLoaded = MAL_TRUE;
|
||||
}
|
||||
if (!pSRC->linear.isNextFramesLoaded) {
|
||||
mal_uint32 framesRead = mal_src_cache_read_frames(&pSRC->cache, 1, pSRC->bin + pSRC->config.channels, pUserData);
|
||||
if (framesRead == 0) {
|
||||
return 0;
|
||||
}
|
||||
pSRC->linear.isNextFramesLoaded = MAL_TRUE;
|
||||
}
|
||||
|
||||
float factor = (float)pSRC->config.sampleRateIn / pSRC->config.sampleRateOut;
|
||||
|
||||
mal_uint64 totalFramesRead = 0;
|
||||
while (frameCount > 0) {
|
||||
// The bin is where the previous and next frames are located.
|
||||
float* pPrevFrame = pSRC->bin;
|
||||
float* pNextFrame = pSRC->bin + pSRC->config.channels;
|
||||
|
||||
float pFrame[MAL_MAX_CHANNELS];
|
||||
mal_blend_f32(pFrame, pPrevFrame, pNextFrame, pSRC->linear.alpha, pSRC->config.channels);
|
||||
|
||||
pSRC->linear.alpha += factor;
|
||||
|
||||
// The new alpha value is how we determine whether or not we need to read fresh frames.
|
||||
mal_uint32 framesToReadFromClient = (mal_uint32)pSRC->linear.alpha;
|
||||
pSRC->linear.alpha = pSRC->linear.alpha - framesToReadFromClient;
|
||||
|
||||
for (mal_uint32 i = 0; i < framesToReadFromClient; ++i) {
|
||||
for (mal_uint32 j = 0; j < pSRC->config.channels; ++j) {
|
||||
pPrevFrame[j] = pNextFrame[j];
|
||||
}
|
||||
|
||||
mal_uint32 framesRead = mal_src_cache_read_frames(&pSRC->cache, 1, pNextFrame, pUserData);
|
||||
if (framesRead == 0) {
|
||||
for (mal_uint32 j = 0; j < pSRC->config.channels; ++j) {
|
||||
pNextFrame[j] = 0;
|
||||
}
|
||||
|
||||
if (pSRC->linear.isNextFramesLoaded) {
|
||||
pSRC->linear.isNextFramesLoaded = MAL_FALSE;
|
||||
} else {
|
||||
if (flush) {
|
||||
pSRC->linear.isPrevFramesLoaded = MAL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//mal_pcm_convert(pFramesOut, pSRC->config.formatOut, pFrame, mal_format_f32, 1 * pSRC->config.channels, mal_dither_mode_none);
|
||||
mal_copy_memory(pFramesOut, pFrame, 1 * pSRC->config.channels * sizeof(float));
|
||||
|
||||
pFramesOut = (mal_uint8*)pFramesOut + (1 * pSRC->config.channels * sizeof(float));
|
||||
frameCount -= 1;
|
||||
totalFramesRead += 1;
|
||||
|
||||
// If there's no frames available we need to get out of this loop.
|
||||
if (!pSRC->linear.isNextFramesLoaded && (!flush || !pSRC->linear.isPrevFramesLoaded)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return totalFramesRead;
|
||||
}
|
||||
#endif
|
||||
|
||||
mal_uint64 mal_src_read_deinterleaved__passthrough(mal_src* pSRC, mal_uint64 frameCount, void** ppSamplesOut, mal_bool32 flush, void* pUserData)
|
||||
{
|
||||
(void)flush; // Passthrough need not care about flushing.
|
||||
@@ -18171,9 +18027,6 @@ mal_uint64 mal_src_read_deinterleaved__linear(mal_src* pSRC, mal_uint64 frameCou
|
||||
ppNextSamplesOut[iChannel] = (float*)ppNextSamplesOut[iChannel] + 1;
|
||||
}
|
||||
|
||||
//float pFrame[MAL_MAX_CHANNELS];
|
||||
//mal_blend_f32(pFrame, pPrevFrame, pNextFrame, pSRC->linear.alpha, pSRC->config.channels);
|
||||
|
||||
pSRC->linear.alpha += factor;
|
||||
|
||||
// The new alpha value is how we determine whether or not we need to read fresh frames.
|
||||
@@ -18203,10 +18056,6 @@ mal_uint64 mal_src_read_deinterleaved__linear(mal_src* pSRC, mal_uint64 frameCou
|
||||
}
|
||||
}
|
||||
|
||||
//mal_pcm_convert(pFramesOut, pSRC->config.formatOut, pFrame, mal_format_f32, 1 * pSRC->config.channels, mal_dither_mode_none);
|
||||
//mal_copy_memory(pFramesOut, pFrame, 1 * pSRC->config.channels * sizeof(float));
|
||||
|
||||
//pFramesOut = (mal_uint8*)pFramesOut + (1 * pSRC->config.channels * sizeof(float));
|
||||
frameCount -= 1;
|
||||
totalFramesRead += 1;
|
||||
|
||||
@@ -18302,472 +18151,6 @@ void mal_pcm_convert(void* pOut, mal_format formatOut, const void* pIn, mal_form
|
||||
}
|
||||
|
||||
|
||||
void mal_rearrange_channels_u8(mal_uint8* pFrame, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS])
|
||||
{
|
||||
mal_channel temp[MAL_MAX_CHANNELS];
|
||||
mal_copy_memory(temp, pFrame, sizeof(temp[0]) * channels);
|
||||
|
||||
switch (channels) {
|
||||
case 32: pFrame[31] = temp[channelMap[31]];
|
||||
case 31: pFrame[30] = temp[channelMap[30]];
|
||||
case 30: pFrame[29] = temp[channelMap[29]];
|
||||
case 29: pFrame[28] = temp[channelMap[28]];
|
||||
case 28: pFrame[27] = temp[channelMap[27]];
|
||||
case 27: pFrame[26] = temp[channelMap[26]];
|
||||
case 26: pFrame[25] = temp[channelMap[25]];
|
||||
case 25: pFrame[24] = temp[channelMap[24]];
|
||||
case 24: pFrame[23] = temp[channelMap[23]];
|
||||
case 23: pFrame[22] = temp[channelMap[22]];
|
||||
case 22: pFrame[21] = temp[channelMap[21]];
|
||||
case 21: pFrame[20] = temp[channelMap[20]];
|
||||
case 20: pFrame[19] = temp[channelMap[19]];
|
||||
case 19: pFrame[18] = temp[channelMap[18]];
|
||||
case 18: pFrame[17] = temp[channelMap[17]];
|
||||
case 17: pFrame[16] = temp[channelMap[16]];
|
||||
case 16: pFrame[15] = temp[channelMap[15]];
|
||||
case 15: pFrame[14] = temp[channelMap[14]];
|
||||
case 14: pFrame[13] = temp[channelMap[13]];
|
||||
case 13: pFrame[12] = temp[channelMap[12]];
|
||||
case 12: pFrame[11] = temp[channelMap[11]];
|
||||
case 11: pFrame[10] = temp[channelMap[10]];
|
||||
case 10: pFrame[ 9] = temp[channelMap[ 9]];
|
||||
case 9: pFrame[ 8] = temp[channelMap[ 8]];
|
||||
case 8: pFrame[ 7] = temp[channelMap[ 7]];
|
||||
case 7: pFrame[ 6] = temp[channelMap[ 6]];
|
||||
case 6: pFrame[ 5] = temp[channelMap[ 5]];
|
||||
case 5: pFrame[ 4] = temp[channelMap[ 4]];
|
||||
case 4: pFrame[ 3] = temp[channelMap[ 3]];
|
||||
case 3: pFrame[ 2] = temp[channelMap[ 2]];
|
||||
case 2: pFrame[ 1] = temp[channelMap[ 1]];
|
||||
case 1: pFrame[ 0] = temp[channelMap[ 0]];
|
||||
}
|
||||
}
|
||||
|
||||
void mal_rearrange_channels_s16(mal_int16* pFrame, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS])
|
||||
{
|
||||
mal_int16 temp[MAL_MAX_CHANNELS];
|
||||
mal_copy_memory(temp, pFrame, sizeof(temp[0]) * channels);
|
||||
|
||||
switch (channels) {
|
||||
case 32: pFrame[31] = temp[channelMap[31]];
|
||||
case 31: pFrame[30] = temp[channelMap[30]];
|
||||
case 30: pFrame[29] = temp[channelMap[29]];
|
||||
case 29: pFrame[28] = temp[channelMap[28]];
|
||||
case 28: pFrame[27] = temp[channelMap[27]];
|
||||
case 27: pFrame[26] = temp[channelMap[26]];
|
||||
case 26: pFrame[25] = temp[channelMap[25]];
|
||||
case 25: pFrame[24] = temp[channelMap[24]];
|
||||
case 24: pFrame[23] = temp[channelMap[23]];
|
||||
case 23: pFrame[22] = temp[channelMap[22]];
|
||||
case 22: pFrame[21] = temp[channelMap[21]];
|
||||
case 21: pFrame[20] = temp[channelMap[20]];
|
||||
case 20: pFrame[19] = temp[channelMap[19]];
|
||||
case 19: pFrame[18] = temp[channelMap[18]];
|
||||
case 18: pFrame[17] = temp[channelMap[17]];
|
||||
case 17: pFrame[16] = temp[channelMap[16]];
|
||||
case 16: pFrame[15] = temp[channelMap[15]];
|
||||
case 15: pFrame[14] = temp[channelMap[14]];
|
||||
case 14: pFrame[13] = temp[channelMap[13]];
|
||||
case 13: pFrame[12] = temp[channelMap[12]];
|
||||
case 12: pFrame[11] = temp[channelMap[11]];
|
||||
case 11: pFrame[10] = temp[channelMap[10]];
|
||||
case 10: pFrame[ 9] = temp[channelMap[ 9]];
|
||||
case 9: pFrame[ 8] = temp[channelMap[ 8]];
|
||||
case 8: pFrame[ 7] = temp[channelMap[ 7]];
|
||||
case 7: pFrame[ 6] = temp[channelMap[ 6]];
|
||||
case 6: pFrame[ 5] = temp[channelMap[ 5]];
|
||||
case 5: pFrame[ 4] = temp[channelMap[ 4]];
|
||||
case 4: pFrame[ 3] = temp[channelMap[ 3]];
|
||||
case 3: pFrame[ 2] = temp[channelMap[ 2]];
|
||||
case 2: pFrame[ 1] = temp[channelMap[ 1]];
|
||||
case 1: pFrame[ 0] = temp[channelMap[ 0]];
|
||||
}
|
||||
}
|
||||
|
||||
void mal_rearrange_channels_s32(mal_int32* pFrame, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS])
|
||||
{
|
||||
mal_int32 temp[MAL_MAX_CHANNELS];
|
||||
mal_copy_memory(temp, pFrame, sizeof(temp[0]) * channels);
|
||||
|
||||
switch (channels) {
|
||||
case 32: pFrame[31] = temp[channelMap[31]];
|
||||
case 31: pFrame[30] = temp[channelMap[30]];
|
||||
case 30: pFrame[29] = temp[channelMap[29]];
|
||||
case 29: pFrame[28] = temp[channelMap[28]];
|
||||
case 28: pFrame[27] = temp[channelMap[27]];
|
||||
case 27: pFrame[26] = temp[channelMap[26]];
|
||||
case 26: pFrame[25] = temp[channelMap[25]];
|
||||
case 25: pFrame[24] = temp[channelMap[24]];
|
||||
case 24: pFrame[23] = temp[channelMap[23]];
|
||||
case 23: pFrame[22] = temp[channelMap[22]];
|
||||
case 22: pFrame[21] = temp[channelMap[21]];
|
||||
case 21: pFrame[20] = temp[channelMap[20]];
|
||||
case 20: pFrame[19] = temp[channelMap[19]];
|
||||
case 19: pFrame[18] = temp[channelMap[18]];
|
||||
case 18: pFrame[17] = temp[channelMap[17]];
|
||||
case 17: pFrame[16] = temp[channelMap[16]];
|
||||
case 16: pFrame[15] = temp[channelMap[15]];
|
||||
case 15: pFrame[14] = temp[channelMap[14]];
|
||||
case 14: pFrame[13] = temp[channelMap[13]];
|
||||
case 13: pFrame[12] = temp[channelMap[12]];
|
||||
case 12: pFrame[11] = temp[channelMap[11]];
|
||||
case 11: pFrame[10] = temp[channelMap[10]];
|
||||
case 10: pFrame[ 9] = temp[channelMap[ 9]];
|
||||
case 9: pFrame[ 8] = temp[channelMap[ 8]];
|
||||
case 8: pFrame[ 7] = temp[channelMap[ 7]];
|
||||
case 7: pFrame[ 6] = temp[channelMap[ 6]];
|
||||
case 6: pFrame[ 5] = temp[channelMap[ 5]];
|
||||
case 5: pFrame[ 4] = temp[channelMap[ 4]];
|
||||
case 4: pFrame[ 3] = temp[channelMap[ 3]];
|
||||
case 3: pFrame[ 2] = temp[channelMap[ 2]];
|
||||
case 2: pFrame[ 1] = temp[channelMap[ 1]];
|
||||
case 1: pFrame[ 0] = temp[channelMap[ 0]];
|
||||
}
|
||||
}
|
||||
|
||||
void mal_rearrange_channels_f32(float* pFrame, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS])
|
||||
{
|
||||
float temp[MAL_MAX_CHANNELS];
|
||||
mal_copy_memory(temp, pFrame, sizeof(temp[0]) * channels);
|
||||
|
||||
switch (channels) {
|
||||
case 32: pFrame[31] = temp[channelMap[31]];
|
||||
case 31: pFrame[30] = temp[channelMap[30]];
|
||||
case 30: pFrame[29] = temp[channelMap[29]];
|
||||
case 29: pFrame[28] = temp[channelMap[28]];
|
||||
case 28: pFrame[27] = temp[channelMap[27]];
|
||||
case 27: pFrame[26] = temp[channelMap[26]];
|
||||
case 26: pFrame[25] = temp[channelMap[25]];
|
||||
case 25: pFrame[24] = temp[channelMap[24]];
|
||||
case 24: pFrame[23] = temp[channelMap[23]];
|
||||
case 23: pFrame[22] = temp[channelMap[22]];
|
||||
case 22: pFrame[21] = temp[channelMap[21]];
|
||||
case 21: pFrame[20] = temp[channelMap[20]];
|
||||
case 20: pFrame[19] = temp[channelMap[19]];
|
||||
case 19: pFrame[18] = temp[channelMap[18]];
|
||||
case 18: pFrame[17] = temp[channelMap[17]];
|
||||
case 17: pFrame[16] = temp[channelMap[16]];
|
||||
case 16: pFrame[15] = temp[channelMap[15]];
|
||||
case 15: pFrame[14] = temp[channelMap[14]];
|
||||
case 14: pFrame[13] = temp[channelMap[13]];
|
||||
case 13: pFrame[12] = temp[channelMap[12]];
|
||||
case 12: pFrame[11] = temp[channelMap[11]];
|
||||
case 11: pFrame[10] = temp[channelMap[10]];
|
||||
case 10: pFrame[ 9] = temp[channelMap[ 9]];
|
||||
case 9: pFrame[ 8] = temp[channelMap[ 8]];
|
||||
case 8: pFrame[ 7] = temp[channelMap[ 7]];
|
||||
case 7: pFrame[ 6] = temp[channelMap[ 6]];
|
||||
case 6: pFrame[ 5] = temp[channelMap[ 5]];
|
||||
case 5: pFrame[ 4] = temp[channelMap[ 4]];
|
||||
case 4: pFrame[ 3] = temp[channelMap[ 3]];
|
||||
case 3: pFrame[ 2] = temp[channelMap[ 2]];
|
||||
case 2: pFrame[ 1] = temp[channelMap[ 1]];
|
||||
case 1: pFrame[ 0] = temp[channelMap[ 0]];
|
||||
}
|
||||
}
|
||||
|
||||
void mal_rearrange_channels_generic(void* pFrame, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS], mal_format format)
|
||||
{
|
||||
mal_uint32 sampleSizeInBytes = mal_get_bytes_per_sample(format);
|
||||
|
||||
mal_uint8 temp[MAL_MAX_CHANNELS * MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES]; // Product of MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES to ensure it's large enough for all formats.
|
||||
mal_copy_memory(temp, pFrame, sampleSizeInBytes * channels);
|
||||
|
||||
switch (channels) {
|
||||
case 32: mal_copy_memory((mal_uint8*)pFrame + (31 * sampleSizeInBytes), &temp[channelMap[31] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 31: mal_copy_memory((mal_uint8*)pFrame + (30 * sampleSizeInBytes), &temp[channelMap[30] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 30: mal_copy_memory((mal_uint8*)pFrame + (29 * sampleSizeInBytes), &temp[channelMap[29] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 29: mal_copy_memory((mal_uint8*)pFrame + (28 * sampleSizeInBytes), &temp[channelMap[28] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 28: mal_copy_memory((mal_uint8*)pFrame + (27 * sampleSizeInBytes), &temp[channelMap[27] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 27: mal_copy_memory((mal_uint8*)pFrame + (26 * sampleSizeInBytes), &temp[channelMap[26] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 26: mal_copy_memory((mal_uint8*)pFrame + (25 * sampleSizeInBytes), &temp[channelMap[25] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 25: mal_copy_memory((mal_uint8*)pFrame + (24 * sampleSizeInBytes), &temp[channelMap[24] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 24: mal_copy_memory((mal_uint8*)pFrame + (23 * sampleSizeInBytes), &temp[channelMap[23] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 23: mal_copy_memory((mal_uint8*)pFrame + (22 * sampleSizeInBytes), &temp[channelMap[22] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 22: mal_copy_memory((mal_uint8*)pFrame + (21 * sampleSizeInBytes), &temp[channelMap[21] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 21: mal_copy_memory((mal_uint8*)pFrame + (20 * sampleSizeInBytes), &temp[channelMap[20] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 20: mal_copy_memory((mal_uint8*)pFrame + (19 * sampleSizeInBytes), &temp[channelMap[19] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 19: mal_copy_memory((mal_uint8*)pFrame + (18 * sampleSizeInBytes), &temp[channelMap[18] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 18: mal_copy_memory((mal_uint8*)pFrame + (17 * sampleSizeInBytes), &temp[channelMap[17] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 17: mal_copy_memory((mal_uint8*)pFrame + (16 * sampleSizeInBytes), &temp[channelMap[16] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 16: mal_copy_memory((mal_uint8*)pFrame + (15 * sampleSizeInBytes), &temp[channelMap[15] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 15: mal_copy_memory((mal_uint8*)pFrame + (14 * sampleSizeInBytes), &temp[channelMap[14] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 14: mal_copy_memory((mal_uint8*)pFrame + (13 * sampleSizeInBytes), &temp[channelMap[13] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 13: mal_copy_memory((mal_uint8*)pFrame + (12 * sampleSizeInBytes), &temp[channelMap[12] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 12: mal_copy_memory((mal_uint8*)pFrame + (11 * sampleSizeInBytes), &temp[channelMap[11] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 11: mal_copy_memory((mal_uint8*)pFrame + (10 * sampleSizeInBytes), &temp[channelMap[10] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 10: mal_copy_memory((mal_uint8*)pFrame + ( 9 * sampleSizeInBytes), &temp[channelMap[ 9] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 9: mal_copy_memory((mal_uint8*)pFrame + ( 8 * sampleSizeInBytes), &temp[channelMap[ 8] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 8: mal_copy_memory((mal_uint8*)pFrame + ( 7 * sampleSizeInBytes), &temp[channelMap[ 7] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 7: mal_copy_memory((mal_uint8*)pFrame + ( 6 * sampleSizeInBytes), &temp[channelMap[ 6] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 6: mal_copy_memory((mal_uint8*)pFrame + ( 5 * sampleSizeInBytes), &temp[channelMap[ 5] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 5: mal_copy_memory((mal_uint8*)pFrame + ( 4 * sampleSizeInBytes), &temp[channelMap[ 4] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 4: mal_copy_memory((mal_uint8*)pFrame + ( 3 * sampleSizeInBytes), &temp[channelMap[ 3] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 3: mal_copy_memory((mal_uint8*)pFrame + ( 2 * sampleSizeInBytes), &temp[channelMap[ 2] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 2: mal_copy_memory((mal_uint8*)pFrame + ( 1 * sampleSizeInBytes), &temp[channelMap[ 1] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
case 1: mal_copy_memory((mal_uint8*)pFrame + ( 0 * sampleSizeInBytes), &temp[channelMap[ 0] * sampleSizeInBytes], sampleSizeInBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void mal_rearrange_channels(void* pFrame, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS], mal_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case mal_format_u8: mal_rearrange_channels_u8( (mal_uint8*)pFrame, channels, channelMap); break;
|
||||
case mal_format_s16: mal_rearrange_channels_s16((mal_int16*)pFrame, channels, channelMap); break;
|
||||
case mal_format_s32: mal_rearrange_channels_s32((mal_int32*)pFrame, channels, channelMap); break;
|
||||
case mal_format_f32: mal_rearrange_channels_f32( (float*)pFrame, channels, channelMap); break;
|
||||
default: mal_rearrange_channels_generic(pFrame, channels, channelMap, format); break;
|
||||
}
|
||||
}
|
||||
|
||||
void mal_dsp_mix_channels__dec(float* pFramesOut, mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], const float* pFramesIn, mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 frameCount, mal_channel_mix_mode mode)
|
||||
{
|
||||
mal_assert(pFramesOut != NULL);
|
||||
mal_assert(channelsOut > 0);
|
||||
mal_assert(pFramesIn != NULL);
|
||||
mal_assert(channelsIn > 0);
|
||||
mal_assert(channelsOut < channelsIn);
|
||||
|
||||
(void)channelMapOut;
|
||||
(void)channelMapIn;
|
||||
|
||||
if (mode == mal_channel_mix_mode_simple) {
|
||||
// Basic mode is where we just drop excess channels.
|
||||
for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) {
|
||||
switch (channelsOut) {
|
||||
case 32: pFramesOut[iFrame*channelsOut+31] = pFramesIn[iFrame*channelsIn+31];
|
||||
case 31: pFramesOut[iFrame*channelsOut+30] = pFramesIn[iFrame*channelsIn+30];
|
||||
case 30: pFramesOut[iFrame*channelsOut+29] = pFramesIn[iFrame*channelsIn+29];
|
||||
case 29: pFramesOut[iFrame*channelsOut+28] = pFramesIn[iFrame*channelsIn+28];
|
||||
case 28: pFramesOut[iFrame*channelsOut+27] = pFramesIn[iFrame*channelsIn+27];
|
||||
case 27: pFramesOut[iFrame*channelsOut+26] = pFramesIn[iFrame*channelsIn+26];
|
||||
case 26: pFramesOut[iFrame*channelsOut+25] = pFramesIn[iFrame*channelsIn+25];
|
||||
case 25: pFramesOut[iFrame*channelsOut+24] = pFramesIn[iFrame*channelsIn+24];
|
||||
case 24: pFramesOut[iFrame*channelsOut+23] = pFramesIn[iFrame*channelsIn+23];
|
||||
case 23: pFramesOut[iFrame*channelsOut+22] = pFramesIn[iFrame*channelsIn+22];
|
||||
case 22: pFramesOut[iFrame*channelsOut+21] = pFramesIn[iFrame*channelsIn+21];
|
||||
case 21: pFramesOut[iFrame*channelsOut+20] = pFramesIn[iFrame*channelsIn+20];
|
||||
case 20: pFramesOut[iFrame*channelsOut+19] = pFramesIn[iFrame*channelsIn+19];
|
||||
case 19: pFramesOut[iFrame*channelsOut+18] = pFramesIn[iFrame*channelsIn+18];
|
||||
case 18: pFramesOut[iFrame*channelsOut+17] = pFramesIn[iFrame*channelsIn+17];
|
||||
case 17: pFramesOut[iFrame*channelsOut+16] = pFramesIn[iFrame*channelsIn+16];
|
||||
case 16: pFramesOut[iFrame*channelsOut+15] = pFramesIn[iFrame*channelsIn+15];
|
||||
case 15: pFramesOut[iFrame*channelsOut+14] = pFramesIn[iFrame*channelsIn+14];
|
||||
case 14: pFramesOut[iFrame*channelsOut+13] = pFramesIn[iFrame*channelsIn+13];
|
||||
case 13: pFramesOut[iFrame*channelsOut+12] = pFramesIn[iFrame*channelsIn+12];
|
||||
case 12: pFramesOut[iFrame*channelsOut+11] = pFramesIn[iFrame*channelsIn+11];
|
||||
case 11: pFramesOut[iFrame*channelsOut+10] = pFramesIn[iFrame*channelsIn+10];
|
||||
case 10: pFramesOut[iFrame*channelsOut+ 9] = pFramesIn[iFrame*channelsIn+ 9];
|
||||
case 9: pFramesOut[iFrame*channelsOut+ 8] = pFramesIn[iFrame*channelsIn+ 8];
|
||||
case 8: pFramesOut[iFrame*channelsOut+ 7] = pFramesIn[iFrame*channelsIn+ 7];
|
||||
case 7: pFramesOut[iFrame*channelsOut+ 6] = pFramesIn[iFrame*channelsIn+ 6];
|
||||
case 6: pFramesOut[iFrame*channelsOut+ 5] = pFramesIn[iFrame*channelsIn+ 5];
|
||||
case 5: pFramesOut[iFrame*channelsOut+ 4] = pFramesIn[iFrame*channelsIn+ 4];
|
||||
case 4: pFramesOut[iFrame*channelsOut+ 3] = pFramesIn[iFrame*channelsIn+ 3];
|
||||
case 3: pFramesOut[iFrame*channelsOut+ 2] = pFramesIn[iFrame*channelsIn+ 2];
|
||||
case 2: pFramesOut[iFrame*channelsOut+ 1] = pFramesIn[iFrame*channelsIn+ 1];
|
||||
case 1: pFramesOut[iFrame*channelsOut+ 0] = pFramesIn[iFrame*channelsIn+ 0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Blend mode is where we just use simple averaging to blend based on spacial locality.
|
||||
if (channelsOut == 1) {
|
||||
for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) {
|
||||
float total = 0;
|
||||
switch (channelsIn) {
|
||||
case 32: total += pFramesIn[iFrame*channelsIn+31];
|
||||
case 31: total += pFramesIn[iFrame*channelsIn+30];
|
||||
case 30: total += pFramesIn[iFrame*channelsIn+29];
|
||||
case 29: total += pFramesIn[iFrame*channelsIn+28];
|
||||
case 28: total += pFramesIn[iFrame*channelsIn+27];
|
||||
case 27: total += pFramesIn[iFrame*channelsIn+26];
|
||||
case 26: total += pFramesIn[iFrame*channelsIn+25];
|
||||
case 25: total += pFramesIn[iFrame*channelsIn+24];
|
||||
case 24: total += pFramesIn[iFrame*channelsIn+23];
|
||||
case 23: total += pFramesIn[iFrame*channelsIn+22];
|
||||
case 22: total += pFramesIn[iFrame*channelsIn+21];
|
||||
case 21: total += pFramesIn[iFrame*channelsIn+20];
|
||||
case 20: total += pFramesIn[iFrame*channelsIn+19];
|
||||
case 19: total += pFramesIn[iFrame*channelsIn+18];
|
||||
case 18: total += pFramesIn[iFrame*channelsIn+17];
|
||||
case 17: total += pFramesIn[iFrame*channelsIn+16];
|
||||
case 16: total += pFramesIn[iFrame*channelsIn+15];
|
||||
case 15: total += pFramesIn[iFrame*channelsIn+14];
|
||||
case 14: total += pFramesIn[iFrame*channelsIn+13];
|
||||
case 13: total += pFramesIn[iFrame*channelsIn+12];
|
||||
case 12: total += pFramesIn[iFrame*channelsIn+11];
|
||||
case 11: total += pFramesIn[iFrame*channelsIn+10];
|
||||
case 10: total += pFramesIn[iFrame*channelsIn+ 9];
|
||||
case 9: total += pFramesIn[iFrame*channelsIn+ 8];
|
||||
case 8: total += pFramesIn[iFrame*channelsIn+ 7];
|
||||
case 7: total += pFramesIn[iFrame*channelsIn+ 6];
|
||||
case 6: total += pFramesIn[iFrame*channelsIn+ 5];
|
||||
case 5: total += pFramesIn[iFrame*channelsIn+ 4];
|
||||
case 4: total += pFramesIn[iFrame*channelsIn+ 3];
|
||||
case 3: total += pFramesIn[iFrame*channelsIn+ 2];
|
||||
case 2: total += pFramesIn[iFrame*channelsIn+ 1];
|
||||
case 1: total += pFramesIn[iFrame*channelsIn+ 0];
|
||||
}
|
||||
|
||||
pFramesOut[iFrame+0] = total / channelsIn;
|
||||
}
|
||||
} else if (channelsOut == 2) {
|
||||
// TODO: Implement proper stereo blending.
|
||||
mal_dsp_mix_channels__dec(pFramesOut, channelsOut, channelMapOut, pFramesIn, channelsIn, channelMapIn, frameCount, mal_channel_mix_mode_simple);
|
||||
} else {
|
||||
// Fall back to basic mode.
|
||||
mal_dsp_mix_channels__dec(pFramesOut, channelsOut, channelMapOut, pFramesIn, channelsIn, channelMapIn, frameCount, mal_channel_mix_mode_simple);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mal_dsp_mix_channels__inc(float* pFramesOut, mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], const float* pFramesIn, mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 frameCount, mal_channel_mix_mode mode)
|
||||
{
|
||||
mal_assert(pFramesOut != NULL);
|
||||
mal_assert(channelsOut > 0);
|
||||
mal_assert(pFramesIn != NULL);
|
||||
mal_assert(channelsIn > 0);
|
||||
mal_assert(channelsOut > channelsIn);
|
||||
|
||||
(void)channelMapOut;
|
||||
(void)channelMapIn;
|
||||
|
||||
if (mode == mal_channel_mix_mode_simple) {
|
||||
// Basic mode is where we just zero out extra channels.
|
||||
for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) {
|
||||
switch (channelsIn) {
|
||||
case 32: pFramesOut[iFrame*channelsOut+31] = pFramesIn[iFrame*channelsIn+31];
|
||||
case 31: pFramesOut[iFrame*channelsOut+30] = pFramesIn[iFrame*channelsIn+30];
|
||||
case 30: pFramesOut[iFrame*channelsOut+29] = pFramesIn[iFrame*channelsIn+29];
|
||||
case 29: pFramesOut[iFrame*channelsOut+28] = pFramesIn[iFrame*channelsIn+28];
|
||||
case 28: pFramesOut[iFrame*channelsOut+27] = pFramesIn[iFrame*channelsIn+27];
|
||||
case 27: pFramesOut[iFrame*channelsOut+26] = pFramesIn[iFrame*channelsIn+26];
|
||||
case 26: pFramesOut[iFrame*channelsOut+25] = pFramesIn[iFrame*channelsIn+25];
|
||||
case 25: pFramesOut[iFrame*channelsOut+24] = pFramesIn[iFrame*channelsIn+24];
|
||||
case 24: pFramesOut[iFrame*channelsOut+23] = pFramesIn[iFrame*channelsIn+23];
|
||||
case 23: pFramesOut[iFrame*channelsOut+22] = pFramesIn[iFrame*channelsIn+22];
|
||||
case 22: pFramesOut[iFrame*channelsOut+21] = pFramesIn[iFrame*channelsIn+21];
|
||||
case 21: pFramesOut[iFrame*channelsOut+20] = pFramesIn[iFrame*channelsIn+20];
|
||||
case 20: pFramesOut[iFrame*channelsOut+19] = pFramesIn[iFrame*channelsIn+19];
|
||||
case 19: pFramesOut[iFrame*channelsOut+18] = pFramesIn[iFrame*channelsIn+18];
|
||||
case 18: pFramesOut[iFrame*channelsOut+17] = pFramesIn[iFrame*channelsIn+17];
|
||||
case 17: pFramesOut[iFrame*channelsOut+16] = pFramesIn[iFrame*channelsIn+16];
|
||||
case 16: pFramesOut[iFrame*channelsOut+15] = pFramesIn[iFrame*channelsIn+15];
|
||||
case 15: pFramesOut[iFrame*channelsOut+14] = pFramesIn[iFrame*channelsIn+14];
|
||||
case 14: pFramesOut[iFrame*channelsOut+13] = pFramesIn[iFrame*channelsIn+13];
|
||||
case 13: pFramesOut[iFrame*channelsOut+12] = pFramesIn[iFrame*channelsIn+12];
|
||||
case 12: pFramesOut[iFrame*channelsOut+11] = pFramesIn[iFrame*channelsIn+11];
|
||||
case 11: pFramesOut[iFrame*channelsOut+10] = pFramesIn[iFrame*channelsIn+10];
|
||||
case 10: pFramesOut[iFrame*channelsOut+ 9] = pFramesIn[iFrame*channelsIn+ 9];
|
||||
case 9: pFramesOut[iFrame*channelsOut+ 8] = pFramesIn[iFrame*channelsIn+ 8];
|
||||
case 8: pFramesOut[iFrame*channelsOut+ 7] = pFramesIn[iFrame*channelsIn+ 7];
|
||||
case 7: pFramesOut[iFrame*channelsOut+ 6] = pFramesIn[iFrame*channelsIn+ 6];
|
||||
case 6: pFramesOut[iFrame*channelsOut+ 5] = pFramesIn[iFrame*channelsIn+ 5];
|
||||
case 5: pFramesOut[iFrame*channelsOut+ 4] = pFramesIn[iFrame*channelsIn+ 4];
|
||||
case 4: pFramesOut[iFrame*channelsOut+ 3] = pFramesIn[iFrame*channelsIn+ 3];
|
||||
case 3: pFramesOut[iFrame*channelsOut+ 2] = pFramesIn[iFrame*channelsIn+ 2];
|
||||
case 2: pFramesOut[iFrame*channelsOut+ 1] = pFramesIn[iFrame*channelsIn+ 1];
|
||||
case 1: pFramesOut[iFrame*channelsOut+ 0] = pFramesIn[iFrame*channelsIn+ 0];
|
||||
}
|
||||
|
||||
// Zero out extra channels.
|
||||
switch (channelsOut - channelsIn) {
|
||||
case 32: pFramesOut[iFrame*channelsOut+31 + channelsIn] = 0;
|
||||
case 31: pFramesOut[iFrame*channelsOut+30 + channelsIn] = 0;
|
||||
case 30: pFramesOut[iFrame*channelsOut+29 + channelsIn] = 0;
|
||||
case 29: pFramesOut[iFrame*channelsOut+28 + channelsIn] = 0;
|
||||
case 28: pFramesOut[iFrame*channelsOut+27 + channelsIn] = 0;
|
||||
case 27: pFramesOut[iFrame*channelsOut+26 + channelsIn] = 0;
|
||||
case 26: pFramesOut[iFrame*channelsOut+25 + channelsIn] = 0;
|
||||
case 25: pFramesOut[iFrame*channelsOut+24 + channelsIn] = 0;
|
||||
case 24: pFramesOut[iFrame*channelsOut+23 + channelsIn] = 0;
|
||||
case 23: pFramesOut[iFrame*channelsOut+22 + channelsIn] = 0;
|
||||
case 22: pFramesOut[iFrame*channelsOut+21 + channelsIn] = 0;
|
||||
case 21: pFramesOut[iFrame*channelsOut+20 + channelsIn] = 0;
|
||||
case 20: pFramesOut[iFrame*channelsOut+19 + channelsIn] = 0;
|
||||
case 19: pFramesOut[iFrame*channelsOut+18 + channelsIn] = 0;
|
||||
case 18: pFramesOut[iFrame*channelsOut+17 + channelsIn] = 0;
|
||||
case 17: pFramesOut[iFrame*channelsOut+16 + channelsIn] = 0;
|
||||
case 16: pFramesOut[iFrame*channelsOut+15 + channelsIn] = 0;
|
||||
case 15: pFramesOut[iFrame*channelsOut+14 + channelsIn] = 0;
|
||||
case 14: pFramesOut[iFrame*channelsOut+13 + channelsIn] = 0;
|
||||
case 13: pFramesOut[iFrame*channelsOut+12 + channelsIn] = 0;
|
||||
case 12: pFramesOut[iFrame*channelsOut+11 + channelsIn] = 0;
|
||||
case 11: pFramesOut[iFrame*channelsOut+10 + channelsIn] = 0;
|
||||
case 10: pFramesOut[iFrame*channelsOut+ 9 + channelsIn] = 0;
|
||||
case 9: pFramesOut[iFrame*channelsOut+ 8 + channelsIn] = 0;
|
||||
case 8: pFramesOut[iFrame*channelsOut+ 7 + channelsIn] = 0;
|
||||
case 7: pFramesOut[iFrame*channelsOut+ 6 + channelsIn] = 0;
|
||||
case 6: pFramesOut[iFrame*channelsOut+ 5 + channelsIn] = 0;
|
||||
case 5: pFramesOut[iFrame*channelsOut+ 4 + channelsIn] = 0;
|
||||
case 4: pFramesOut[iFrame*channelsOut+ 3 + channelsIn] = 0;
|
||||
case 3: pFramesOut[iFrame*channelsOut+ 2 + channelsIn] = 0;
|
||||
case 2: pFramesOut[iFrame*channelsOut+ 1 + channelsIn] = 0;
|
||||
case 1: pFramesOut[iFrame*channelsOut+ 0 + channelsIn] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Using blended mixing mode. Basically this is just the mode where audio is distributed across all channels
|
||||
// based on spacial locality.
|
||||
if (channelsIn == 1) {
|
||||
for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) {
|
||||
switch (channelsOut) {
|
||||
case 32: pFramesOut[iFrame*channelsOut+31] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 31: pFramesOut[iFrame*channelsOut+30] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 30: pFramesOut[iFrame*channelsOut+29] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 29: pFramesOut[iFrame*channelsOut+28] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 28: pFramesOut[iFrame*channelsOut+27] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 27: pFramesOut[iFrame*channelsOut+26] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 26: pFramesOut[iFrame*channelsOut+25] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 25: pFramesOut[iFrame*channelsOut+24] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 24: pFramesOut[iFrame*channelsOut+23] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 23: pFramesOut[iFrame*channelsOut+22] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 22: pFramesOut[iFrame*channelsOut+21] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 21: pFramesOut[iFrame*channelsOut+20] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 20: pFramesOut[iFrame*channelsOut+19] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 19: pFramesOut[iFrame*channelsOut+18] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 18: pFramesOut[iFrame*channelsOut+17] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 17: pFramesOut[iFrame*channelsOut+16] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 16: pFramesOut[iFrame*channelsOut+15] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 15: pFramesOut[iFrame*channelsOut+14] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 14: pFramesOut[iFrame*channelsOut+13] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 13: pFramesOut[iFrame*channelsOut+12] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 12: pFramesOut[iFrame*channelsOut+11] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 11: pFramesOut[iFrame*channelsOut+10] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 10: pFramesOut[iFrame*channelsOut+ 9] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 9: pFramesOut[iFrame*channelsOut+ 8] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 8: pFramesOut[iFrame*channelsOut+ 7] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 7: pFramesOut[iFrame*channelsOut+ 6] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 6: pFramesOut[iFrame*channelsOut+ 5] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 5: pFramesOut[iFrame*channelsOut+ 4] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 4: pFramesOut[iFrame*channelsOut+ 3] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 3: pFramesOut[iFrame*channelsOut+ 2] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 2: pFramesOut[iFrame*channelsOut+ 1] = pFramesIn[iFrame*channelsIn+0];
|
||||
case 1: pFramesOut[iFrame*channelsOut+ 0] = pFramesIn[iFrame*channelsIn+0];
|
||||
}
|
||||
}
|
||||
} else if (channelsIn == 2) {
|
||||
// TODO: Implement an optimized stereo conversion.
|
||||
mal_dsp_mix_channels__inc(pFramesOut, channelsOut, channelMapOut, pFramesIn, channelsIn, channelMapIn, frameCount, mal_channel_mix_mode_simple);
|
||||
} else {
|
||||
// Fall back to basic mixing mode.
|
||||
mal_dsp_mix_channels__inc(pFramesOut, channelsOut, channelMapOut, pFramesIn, channelsIn, channelMapIn, frameCount, mal_channel_mix_mode_simple);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mal_dsp_mix_channels(float* pFramesOut, mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], const float* pFramesIn, mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 frameCount, mal_channel_mix_mode mode)
|
||||
{
|
||||
if (channelsIn < channelsOut) {
|
||||
// Increasing the channel count.
|
||||
mal_dsp_mix_channels__inc(pFramesOut, channelsOut, channelMapOut, pFramesIn, channelsIn, channelMapIn, frameCount, mode);
|
||||
} else {
|
||||
// Decreasing the channel count.
|
||||
mal_dsp_mix_channels__dec(pFramesOut, channelsOut, channelMapOut, pFramesIn, channelsIn, channelMapIn, frameCount, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -18828,18 +18211,6 @@ mal_uint32 mal_dsp__post_format_converter_on_read_deinterleaved(mal_format_conve
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
mal_uint32 mal_dsp__src_on_read(mal_src* pSRC, mal_uint32 frameCount, void* pFramesOut, void* pUserData)
|
||||
{
|
||||
(void)pSRC;
|
||||
|
||||
mal_dsp* pDSP = (mal_dsp*)pUserData;
|
||||
mal_assert(pDSP != NULL);
|
||||
|
||||
return pDSP->onRead(pDSP, frameCount, pFramesOut, pDSP->pUserData);
|
||||
}
|
||||
#endif
|
||||
|
||||
mal_uint32 mal_dsp__src_on_read_deinterleaved(mal_src* pSRC, mal_uint32 frameCount, void** ppSamplesOut, void* pUserData)
|
||||
{
|
||||
(void)pSRC;
|
||||
@@ -19049,70 +18420,6 @@ mal_result mal_dsp_init(const mal_dsp_config* pConfig, mal_dsp* pDSP)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
pDSP->isChannelMappingRequired = MAL_FALSE;
|
||||
if (pConfig->channelMapIn[0] != MAL_CHANNEL_NONE && pConfig->channelMapOut[0] != MAL_CHANNEL_NONE) { // <-- Channel mapping will be ignored if the first channel map is MAL_CHANNEL_NONE.
|
||||
// When using channel mapping we need to figure out a shuffling table. The first thing to do is convert the input channel map
|
||||
// so that it contains the same number of channels as the output channel count.
|
||||
mal_uint32 iChannel;
|
||||
mal_uint32 channelsMin = mal_min(pConfig->channelsIn, pConfig->channelsOut);
|
||||
for (iChannel = 0; iChannel < channelsMin; ++iChannel) {
|
||||
pDSP->channelMapInPostMix[iChannel] = pConfig->channelMapIn[iChannel];
|
||||
}
|
||||
|
||||
// Any excess channels need to be filled with the relevant channels from the output channel map. Currently we're justing filling it with
|
||||
// the first channels that are not present in the input channel map.
|
||||
if (pConfig->channelsOut > pConfig->channelsIn) {
|
||||
for (iChannel = pConfig->channelsIn; iChannel < pConfig->channelsOut; ++iChannel) {
|
||||
mal_uint8 newChannel = MAL_CHANNEL_NONE;
|
||||
for (mal_uint32 iChannelOut = 0; iChannelOut < pConfig->channelsOut; ++iChannelOut) {
|
||||
mal_bool32 exists = MAL_FALSE;
|
||||
for (mal_uint32 iChannelIn = 0; iChannelIn < pConfig->channelsIn; ++iChannelIn) {
|
||||
if (pConfig->channelMapOut[iChannelOut] == pConfig->channelMapIn[iChannelIn]) {
|
||||
exists = MAL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
newChannel = pConfig->channelMapOut[iChannelOut];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pDSP->channelMapInPostMix[iChannel] = newChannel;
|
||||
}
|
||||
}
|
||||
|
||||
// We only need to do a channel mapping if the map after mixing is different to the final output map.
|
||||
for (iChannel = 0; iChannel < pConfig->channelsOut; ++iChannel) {
|
||||
if (pDSP->channelMapInPostMix[iChannel] != pConfig->channelMapOut[iChannel]) {
|
||||
pDSP->isChannelMappingRequired = MAL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we need to create the shuffling table.
|
||||
if (pDSP->isChannelMappingRequired) {
|
||||
for (mal_uint32 iChannelIn = 0; iChannelIn < pConfig->channelsOut; ++iChannelIn) {
|
||||
for (mal_uint32 iChannelOut = 0; iChannelOut < pConfig->channelsOut; ++iChannelOut) {
|
||||
if (pDSP->channelMapInPostMix[iChannelOut] == pConfig->channelMapOut[iChannelIn]) {
|
||||
pDSP->channelShuffleTable[iChannelOut] = (mal_uint8)iChannelIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pConfig->formatIn == pConfig->formatOut && pConfig->channelsIn == pConfig->channelsOut && pConfig->sampleRateIn == pConfig->sampleRateOut && !pDSP->isChannelMappingRequired) {
|
||||
pDSP->isPassthrough = MAL_TRUE;
|
||||
} else {
|
||||
pDSP->isPassthrough = MAL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return MAL_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -19211,59 +18518,6 @@ mal_uint64 mal_dsp_read_ex(mal_dsp* pDSP, mal_uint64 frameCount, void* pFramesOu
|
||||
data.flush = flush;
|
||||
data.pUserDataForClient = pUserData;
|
||||
return mal_format_converter_read(&pDSP->formatConverterOut, frameCount, pFramesOut, &data);
|
||||
|
||||
|
||||
#if 0
|
||||
// Slower path - where the real work is done.
|
||||
mal_uint8 pFrames[2][MAL_MAX_CHANNELS * 512 * MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES];
|
||||
|
||||
mal_uint64 totalFramesRead = 0;
|
||||
while (frameCount > 0) {
|
||||
mal_uint32 iFrames = 0; // <-- Used as an index into pFrames and cycles between 0 and 1.
|
||||
|
||||
mal_uint32 framesToRead = mal_countof(pFrames[0]) / (mal_max(pDSP->channelRouter.config.channelsIn, pDSP->channelRouter.config.channelsOut) * MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES);
|
||||
if (framesToRead > frameCount) {
|
||||
framesToRead = (mal_uint32)frameCount;
|
||||
}
|
||||
|
||||
// The initial filling of sample data depends on whether or not we are using SRC.
|
||||
mal_uint32 framesRead = 0;
|
||||
if (pDSP->isSRCRequired) {
|
||||
framesRead = (mal_uint32)mal_src_read_ex(&pDSP->src, framesToRead, pFrames[iFrames], flush, pUserData);
|
||||
} else {
|
||||
framesRead = pDSP->onRead(pDSP, framesToRead, pFrames[iFrames], pUserData);
|
||||
}
|
||||
|
||||
if (framesRead == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Channel mixing. The input format must be in f32 which may require a conversion.
|
||||
if (pDSP->channelRouter.config.channelsIn != pDSP->channelRouter.config.channelsOut) {
|
||||
mal_dsp_mix_channels((float*)(pFrames[(iFrames + 1) % 2]), pDSP->channelRouter.config.channelsOut, pDSP->channelRouter.config.channelMapOut, (const float*)(pFrames[iFrames]), pDSP->channelRouter.config.channelsIn, pDSP->channelRouter.config.channelMapIn, framesRead, pDSP->channelRouter.config.mixingMode);
|
||||
iFrames = (iFrames + 1) % 2;
|
||||
}
|
||||
|
||||
|
||||
// Channel mapping.
|
||||
if (pDSP->isChannelMappingRequired) {
|
||||
for (mal_uint32 i = 0; i < framesRead; ++i) {
|
||||
mal_rearrange_channels(pFrames[iFrames] + (i * pDSP->channelRouter.config.channelsOut * mal_get_bytes_per_sample(mal_format_f32)), pDSP->channelRouter.config.channelsOut, pDSP->channelShuffleTable, mal_format_f32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Final conversion to output format.
|
||||
mal_pcm_convert(pFramesOut, pDSP->formatConverterOut.config.formatOut, pFrames[iFrames], mal_format_f32, framesRead * pDSP->channelRouter.config.channelsOut, mal_dither_mode_none);
|
||||
|
||||
pFramesOut = (mal_uint8*)pFramesOut + (framesRead * pDSP->channelRouter.config.channelsOut * mal_get_bytes_per_sample(pDSP->formatConverterOut.config.formatOut));
|
||||
frameCount -= framesRead;
|
||||
totalFramesRead += framesRead;
|
||||
}
|
||||
|
||||
return totalFramesRead;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user