mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Minor tweaks to the resampler.
This commit is contained in:
+16
-12
@@ -47,7 +47,9 @@ Random Notes:
|
||||
#define MAL_RESAMPLER_SEEK_NO_CLIENT_READ (1 << 0) /* When set, does not read anything from the client when seeking. This does _not_ call onRead(). */
|
||||
#define MAL_RESAMPLER_SEEK_INPUT_RATE (1 << 1) /* When set, treats the specified frame count based on the input sample rate rather than the output sample rate. */
|
||||
|
||||
#ifndef MAL_RESAMPLER_CACHE_SIZE_IN_BYTES
|
||||
#define MAL_RESAMPLER_CACHE_SIZE_IN_BYTES 4096
|
||||
#endif
|
||||
|
||||
typedef struct mal_resampler mal_resampler;
|
||||
|
||||
@@ -91,7 +93,7 @@ struct mal_resampler
|
||||
{
|
||||
float f32[MAL_RESAMPLER_CACHE_SIZE_IN_BYTES/sizeof(float)];
|
||||
mal_int16 s16[MAL_RESAMPLER_CACHE_SIZE_IN_BYTES/sizeof(mal_int16)];
|
||||
} cache; /* Do not use directly. Keep this as the first member of this structure for SIMD alignment purposes. */
|
||||
} cache; /* Keep this as the first member of this structure for SIMD alignment purposes. */
|
||||
mal_uint32 cacheStrideInFrames; /* The number of the samples between channels in the cache. The first sample for channel 0 is cacheStrideInFrames*0. The first sample for channel 1 is cacheStrideInFrames*1, etc. */
|
||||
mal_uint16 cacheLengthInFrames; /* The number of valid frames sitting in the cache, including the filter window. May be less than the cache's capacity. */
|
||||
mal_uint16 windowLength;
|
||||
@@ -120,6 +122,8 @@ mal_result mal_resampler_set_rate(mal_resampler* pResampler, mal_uint32 sampleRa
|
||||
|
||||
/*
|
||||
Dynamically adjusts the sample rate by a ratio.
|
||||
|
||||
The ratio is in/out.
|
||||
*/
|
||||
mal_result mal_resampler_set_rate_ratio(mal_resampler* pResampler, double ratio);
|
||||
|
||||
@@ -163,7 +167,7 @@ When the end of input mode is set to mal_resampler_end_of_input_mode_no_consume,
|
||||
window are not included in the calculation.
|
||||
|
||||
This can return a negative value if nothing has yet been loaded into the internal cache. This will happen if this is called
|
||||
immediately after initialization, before the first read has been performed, and may also happen if only a few samples have
|
||||
immediately after initialization, before the first read has been performed. It may also happen if only a few samples have
|
||||
been read from the client.
|
||||
*/
|
||||
double mal_resampler_get_cached_input_time(mal_resampler* pResampler);
|
||||
@@ -175,9 +179,7 @@ of time in output rate making up the cached output.
|
||||
When the end of input mode is set to mal_resampler_end_of_input_mode_no_consume, the input frames currently sitting in the
|
||||
window are not included in the calculation.
|
||||
|
||||
This can return a negative value if nothing has yet been loaded into the internal cache. This will happen if this is called
|
||||
immediately after initialization, before the first read has been performed, and may also happen if only a few samples have
|
||||
been read from the client.
|
||||
This can return a negative value. See mal_resampler_get_cached_input_time() for details.
|
||||
*/
|
||||
double mal_resampler_get_cached_output_time(mal_resampler* pResampler);
|
||||
|
||||
@@ -394,7 +396,7 @@ typedef union
|
||||
|
||||
mal_uint64 mal_resampler_read(mal_resampler* pResampler, mal_uint64 frameCount, void** ppFrames)
|
||||
{
|
||||
mal_uint64 framesRead;
|
||||
mal_uint64 totalFramesRead;
|
||||
mal_resampler_deinterleaved_pointers runningFramesOut;
|
||||
mal_bool32 atEnd = MAL_FALSE;
|
||||
|
||||
@@ -429,14 +431,15 @@ mal_uint64 mal_resampler_read(mal_resampler* pResampler, mal_uint64 frameCount,
|
||||
because they do not need to worry about cache reloading logic. Instead we do all of the cache reloading stuff from here.
|
||||
*/
|
||||
|
||||
framesRead = 0;
|
||||
while (framesRead < frameCount) {
|
||||
totalFramesRead = 0;
|
||||
while (totalFramesRead < frameCount) {
|
||||
double cachedOutputTime;
|
||||
mal_uint64 framesRemaining = frameCount - framesRead;
|
||||
mal_uint64 framesRemaining = frameCount - totalFramesRead;
|
||||
mal_uint64 framesToReadRightNow = framesRemaining;
|
||||
|
||||
/* We need to make sure we don't read more than what's already in the buffer at a time. */
|
||||
cachedOutputTime = mal_resampler_get_cached_output_time(pResampler);
|
||||
if (cachedOutputTime > 0) {
|
||||
if (framesRemaining > cachedOutputTime) {
|
||||
framesToReadRightNow = (mal_uint64)floor(cachedOutputTime);
|
||||
}
|
||||
@@ -493,10 +496,11 @@ mal_uint64 mal_resampler_read(mal_resampler* pResampler, mal_uint64 frameCount,
|
||||
}
|
||||
|
||||
/* We don't want to reload the buffer if we've finished reading. */
|
||||
framesRead += framesToReadRightNow;
|
||||
if (framesRead == frameCount) {
|
||||
totalFramesRead += framesToReadRightNow;
|
||||
if (totalFramesRead == frameCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
We need to exit if we've reached the end of the input buffer. We do not want to attempt to read more data, nor
|
||||
@@ -561,7 +565,7 @@ mal_uint64 mal_resampler_read(mal_resampler* pResampler, mal_uint64 frameCount,
|
||||
}
|
||||
}
|
||||
|
||||
return framesRead;
|
||||
return totalFramesRead;
|
||||
}
|
||||
|
||||
mal_uint64 mal_resampler_seek(mal_resampler* pResampler, mal_uint64 frameCount, mal_uint32 options)
|
||||
|
||||
Reference in New Issue
Block a user