Commit 02e38915 authored by David Reid's avatar David Reid

Fixes to sinc SRC.

parent 1f905996
...@@ -552,7 +552,7 @@ typedef struct ...@@ -552,7 +552,7 @@ typedef struct
#define MAL_MAX_SAMPLE_RATE MAL_SAMPLE_RATE_384000 #define MAL_MAX_SAMPLE_RATE MAL_SAMPLE_RATE_384000
#define MAL_SRC_SINC_MIN_WINDOW_WIDTH 2 #define MAL_SRC_SINC_MIN_WINDOW_WIDTH 2
#define MAL_SRC_SINC_MAX_WINDOW_WIDTH 32 #define MAL_SRC_SINC_MAX_WINDOW_WIDTH 32
#define MAL_SRC_SINC_DEFAULT_WINDOW_WIDTH 4 #define MAL_SRC_SINC_DEFAULT_WINDOW_WIDTH 16
#define MAL_SRC_SINC_LOOKUP_TABLE_RESOLUTION 8 #define MAL_SRC_SINC_LOOKUP_TABLE_RESOLUTION 8
#define MAL_SRC_INPUT_BUFFER_SIZE_IN_SAMPLES 256 #define MAL_SRC_INPUT_BUFFER_SIZE_IN_SAMPLES 256
...@@ -19736,7 +19736,7 @@ mal_uint64 mal_src_read_deinterleaved_ex(mal_src* pSRC, mal_uint64 frameCount, v ...@@ -19736,7 +19736,7 @@ mal_uint64 mal_src_read_deinterleaved_ex(mal_src* pSRC, mal_uint64 frameCount, v
mal_src_algorithm algorithm = pSRC->config.algorithm; mal_src_algorithm algorithm = pSRC->config.algorithm;
if (pSRC->config.sampleRateIn == pSRC->config.sampleRateOut) { if (pSRC->config.sampleRateIn == pSRC->config.sampleRateOut) {
algorithm = mal_src_algorithm_none; //algorithm = mal_src_algorithm_none;
} }
// Can use a function pointer for this. // Can use a function pointer for this.
...@@ -20001,7 +20001,7 @@ static MAL_INLINE float mal_src_sinc__interpolation_factor(const mal_src* pSRC, ...@@ -20001,7 +20001,7 @@ static MAL_INLINE float mal_src_sinc__interpolation_factor(const mal_src* pSRC,
mal_assert(pSRC != NULL); mal_assert(pSRC != NULL);
float xabs = (float)fabs(x); float xabs = (float)fabs(x);
if (xabs >= MAL_SRC_SINC_MAX_WINDOW_WIDTH) { if (xabs >= MAL_SRC_SINC_MAX_WINDOW_WIDTH /*pSRC->config.sinc.windowWidth*/) {
return 0; return 0;
} }
...@@ -20026,7 +20026,6 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount ...@@ -20026,7 +20026,6 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount
float factor = (float)pSRC->config.sampleRateIn / pSRC->config.sampleRateOut; float factor = (float)pSRC->config.sampleRateIn / pSRC->config.sampleRateOut;
float inverseFactor = 1/factor; float inverseFactor = 1/factor;
float sincFactor = ((factor < 1) ? 1 : inverseFactor);
mal_int32 windowWidth = (mal_int32)pSRC->config.sinc.windowWidth; mal_int32 windowWidth = (mal_int32)pSRC->config.sinc.windowWidth;
mal_int32 windowWidth2 = windowWidth*2; mal_int32 windowWidth2 = windowWidth*2;
...@@ -20047,7 +20046,7 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount ...@@ -20047,7 +20046,7 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount
float timeInEnd = (float)(pSRC->sinc.windowPosInSamples + maxInputSamplesAvailableInCache); float timeInEnd = (float)(pSRC->sinc.windowPosInSamples + maxInputSamplesAvailableInCache);
mal_assert(timeInBeg >= 0); mal_assert(timeInBeg >= 0);
mal_assert(timeInEnd <= timeInEnd); mal_assert(timeInBeg <= timeInEnd);
mal_uint64 maxOutputFramesToRead = (mal_uint64)(((timeInEnd - timeInBeg) * inverseFactor)); mal_uint64 maxOutputFramesToRead = (mal_uint64)(((timeInEnd - timeInBeg) * inverseFactor));
...@@ -20068,10 +20067,10 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount ...@@ -20068,10 +20067,10 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount
float t = (timeIn - iTimeIn); float t = (timeIn - iTimeIn);
float w = (float)(iWindow); float w = (float)(iWindow);
float a = mal_src_sinc__interpolation_factor(pSRC, sincFactor * (t - w)); float a = mal_src_sinc__interpolation_factor(pSRC, (t - w));
float s = mal_src_sinc__get_input_sample_from_window(pSRC, iChannel, iTimeIn, iWindow); float s = mal_src_sinc__get_input_sample_from_window(pSRC, iChannel, iTimeIn, iWindow);
sampleOut += sincFactor * s * a; sampleOut += s * a;
} }
ppNextSamplesOut[iChannel][iSample] = (float)sampleOut; ppNextSamplesOut[iChannel][iSample] = (float)sampleOut;
...@@ -20082,24 +20081,20 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount ...@@ -20082,24 +20081,20 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount
ppNextSamplesOut[iChannel] += outputFramesToRead; ppNextSamplesOut[iChannel] += outputFramesToRead;
} }
mal_uint32 inputSamplesFullyConsumed = (mal_uint32)((outputFramesToRead * factor) + timeInBeg); mal_uint32 prevWindowPosInSamples = pSRC->sinc.windowPosInSamples;
pSRC->sinc.timeIn = timeInEnd; pSRC->sinc.timeIn += (outputFramesToRead * factor);
pSRC->sinc.windowPosInSamples = inputSamplesFullyConsumed; pSRC->sinc.windowPosInSamples = (mal_uint32)pSRC->sinc.timeIn;
if (pSRC->sinc.inputFrameCount < inputSamplesFullyConsumed) { pSRC->sinc.inputFrameCount -= pSRC->sinc.windowPosInSamples - prevWindowPosInSamples;
pSRC->sinc.inputFrameCount = 0;
} else {
pSRC->sinc.inputFrameCount -= inputSamplesFullyConsumed;
}
// If the window has reached a point where we cannot read a whole output sample it needs to be moved back to the start. // If the window has reached a point where we cannot read a whole output sample it needs to be moved back to the start.
mal_int32 wholeInputSamplesPerOutputSample = (mal_int32)factor; mal_uint32 availableOutputFrames = (mal_uint32)((timeInEnd - pSRC->sinc.timeIn) * inverseFactor);
if (pSRC->sinc.windowPosInSamples >= (mal_countof(pSRC->sinc.input[0]) - (pSRC->config.sinc.windowWidth*2)) - wholeInputSamplesPerOutputSample) {
if (availableOutputFrames == 0) {
size_t samplesToMove = mal_countof(pSRC->sinc.input[0]) - pSRC->sinc.windowPosInSamples; size_t samplesToMove = mal_countof(pSRC->sinc.input[0]) - pSRC->sinc.windowPosInSamples;
pSRC->sinc.timeIn = timeInEnd - mal_floorf(timeInEnd); pSRC->sinc.timeIn -= mal_floorf(pSRC->sinc.timeIn);
pSRC->sinc.windowPosInSamples = 0; pSRC->sinc.windowPosInSamples = 0;
pSRC->sinc.inputFrameCount = mal_max(pSRC->sinc.inputFrameCount, pSRC->config.sinc.windowWidth);
// Move everything from the end of the cache up to the front. // Move everything from the end of the cache up to the front.
for (mal_uint32 iChannel = 0; iChannel < pSRC->config.channels; iChannel += 1) { for (mal_uint32 iChannel = 0; iChannel < pSRC->config.channels; iChannel += 1) {
...@@ -20117,16 +20112,22 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount ...@@ -20117,16 +20112,22 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount
// Now read data from the client. // Now read data from the client.
mal_uint32 framesToReadFromClient = mal_countof(pSRC->sinc.input[0]) - (pSRC->config.sinc.windowWidth + pSRC->sinc.inputFrameCount); mal_uint32 framesToReadFromClient = mal_countof(pSRC->sinc.input[0]) - (pSRC->config.sinc.windowWidth + pSRC->sinc.inputFrameCount);
if (framesToReadFromClient > 0) { if (framesToReadFromClient > 0) {
pSRC->sinc.inputFrameCount = pSRC->sinc.inputFrameCount + pSRC->config.onReadDeinterleaved(pSRC, framesToReadFromClient, (void**)ppInputDst, pUserData); mal_uint32 framesReadFromClient = pSRC->config.onReadDeinterleaved(pSRC, framesToReadFromClient, (void**)ppInputDst, pUserData);
if (pSRC->sinc.inputFrameCount == 0) { if (framesReadFromClient != 0) {
break; pSRC->sinc.inputFrameCount += framesReadFromClient;
} else {
// We couldn't get anything more from the client. If not more output samples can be computed from the available input samples
// we need to return.
if (((pSRC->sinc.timeIn - pSRC->sinc.inputFrameCount) * inverseFactor) < 1) {
break;
}
} }
} }
// Anything left over in the cache must be set to zero. // Anything left over in the cache must be set to zero.
mal_uint32 leftoverFrames = mal_countof(pSRC->sinc.input[0]) - (pSRC->config.sinc.windowWidth + pSRC->sinc.inputFrameCount); mal_uint32 leftoverFrames = mal_countof(pSRC->sinc.input[0]) - (pSRC->config.sinc.windowWidth + pSRC->sinc.inputFrameCount);
if (leftoverFrames > 0) { if (leftoverFrames > 0) {
for (mal_uint32 iChannel = 0; iChannel < pSRC->config.sinc.windowWidth; iChannel += 1) { for (mal_uint32 iChannel = 0; iChannel < pSRC->config.channels; iChannel += 1) {
mal_zero_memory(pSRC->sinc.input[iChannel] + pSRC->config.sinc.windowWidth + pSRC->sinc.inputFrameCount, leftoverFrames * sizeof(float)); mal_zero_memory(pSRC->sinc.input[iChannel] + pSRC->config.sinc.windowWidth + pSRC->sinc.inputFrameCount, leftoverFrames * sizeof(float));
} }
} }
......
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