Commit 728e3f47 authored by David Reid's avatar David Reid

Clean up.

parent 044a5ba7
......@@ -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
}
......
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