mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-23 16:54:03 +02:00
Add support for clipping.
This only applies when the playback sample format is configured as ma_format_f32. Clipping is enabled by default and can be disabled by setting ma_device_config.noClip to true.
This commit is contained in:
+29
@@ -274,6 +274,9 @@ NOTES
|
|||||||
- The contents of the output buffer passed into the data callback will always be pre-initialized to zero
|
- The contents of the output buffer passed into the data callback will always be pre-initialized to zero
|
||||||
unless the noPreZeroedOutputBuffer config variable in ma_device_config is set to true, in which case
|
unless the noPreZeroedOutputBuffer config variable in ma_device_config is set to true, in which case
|
||||||
it'll be undefined which will require you to write something to the entire buffer.
|
it'll be undefined which will require you to write something to the entire buffer.
|
||||||
|
- By default miniaudio will automatically clip samples. This only applies when the playback sample format
|
||||||
|
is configured as ma_format_f32. If you are doing clipping yourself, you can disable this overhead by
|
||||||
|
setting noClip to true in the device config.
|
||||||
|
|
||||||
|
|
||||||
BACKEND NUANCES
|
BACKEND NUANCES
|
||||||
@@ -1927,6 +1930,7 @@ typedef struct
|
|||||||
ma_uint32 periods;
|
ma_uint32 periods;
|
||||||
ma_performance_profile performanceProfile;
|
ma_performance_profile performanceProfile;
|
||||||
ma_bool32 noPreZeroedOutputBuffer; /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to zero. */
|
ma_bool32 noPreZeroedOutputBuffer; /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to zero. */
|
||||||
|
ma_bool32 noClip; /* When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. Only applies when the playback sample format is f32. */
|
||||||
ma_device_callback_proc dataCallback;
|
ma_device_callback_proc dataCallback;
|
||||||
ma_stop_proc stopCallback;
|
ma_stop_proc stopCallback;
|
||||||
void* pUserData;
|
void* pUserData;
|
||||||
@@ -2380,6 +2384,7 @@ MA_ALIGNED_STRUCT(MA_SIMD_ALIGNMENT) ma_device
|
|||||||
ma_bool32 usingDefaultPeriods : 1;
|
ma_bool32 usingDefaultPeriods : 1;
|
||||||
ma_bool32 isOwnerOfContext : 1; /* When set to true, uninitializing the device will also uninitialize the context. Set to true when NULL is passed into ma_device_init(). */
|
ma_bool32 isOwnerOfContext : 1; /* When set to true, uninitializing the device will also uninitialize the context. Set to true when NULL is passed into ma_device_init(). */
|
||||||
ma_bool32 noPreZeroedOutputBuffer : 1;
|
ma_bool32 noPreZeroedOutputBuffer : 1;
|
||||||
|
ma_bool32 noClip : 1;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char name[256]; /* Maybe temporary. Likely to be replaced with a query API. */
|
char name[256]; /* Maybe temporary. Likely to be replaced with a query API. */
|
||||||
@@ -3026,6 +3031,12 @@ Copies silent frames into the given buffer.
|
|||||||
*/
|
*/
|
||||||
void ma_zero_pcm_frames(void* p, ma_uint32 frameCount, ma_format format, ma_uint32 channels);
|
void ma_zero_pcm_frames(void* p, ma_uint32 frameCount, ma_format format, ma_uint32 channels);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Clips f32 samples.
|
||||||
|
*/
|
||||||
|
void ma_clip_samples_f32(float* p, ma_uint32 sampleCount);
|
||||||
|
MA_INLINE void ma_clip_pcm_frames_f32(float* p, ma_uint32 frameCount, ma_uint32 channels) { ma_clip_samples_f32(p, frameCount*channels); }
|
||||||
|
|
||||||
#endif /* MA_NO_DEVICE_IO */
|
#endif /* MA_NO_DEVICE_IO */
|
||||||
|
|
||||||
|
|
||||||
@@ -5300,6 +5311,16 @@ void ma_zero_pcm_frames(void* p, ma_uint32 frameCount, ma_format format, ma_uint
|
|||||||
ma_zero_memory(p, frameCount * ma_get_bytes_per_frame(format, channels));
|
ma_zero_memory(p, frameCount * ma_get_bytes_per_frame(format, channels));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ma_clip_samples_f32(float* p, ma_uint32 sampleCount)
|
||||||
|
{
|
||||||
|
ma_uint32 iSample;
|
||||||
|
|
||||||
|
/* TODO: Research a branchless SSE implementation. */
|
||||||
|
for (iSample = 0; iSample < sampleCount; iSample += 1) {
|
||||||
|
p[iSample] = ma_clip_f32(p[iSample]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static MA_INLINE void ma_device__on_data(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
|
static MA_INLINE void ma_device__on_data(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
|
||||||
{
|
{
|
||||||
@@ -5312,6 +5333,10 @@ static MA_INLINE void ma_device__on_data(ma_device* pDevice, void* pFramesOut, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
onData(pDevice, pFramesOut, pFramesIn, frameCount);
|
onData(pDevice, pFramesOut, pFramesIn, frameCount);
|
||||||
|
|
||||||
|
if (!pDevice->noClip && pFramesOut != NULL && pDevice->playback.format == ma_format_f32) {
|
||||||
|
ma_clip_pcm_frames_f32((float*)pFramesOut, frameCount, pDevice->playback.channels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25699,6 +25724,7 @@ ma_result ma_device_init(ma_context* pContext, const ma_device_config* pConfig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pDevice->noPreZeroedOutputBuffer = config.noPreZeroedOutputBuffer;
|
pDevice->noPreZeroedOutputBuffer = config.noPreZeroedOutputBuffer;
|
||||||
|
pDevice->noClip = config.noClip;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When passing in 0 for the format/channels/rate/chmap it means the device will be using whatever is chosen by the backend. If everything is set
|
When passing in 0 for the format/channels/rate/chmap it means the device will be using whatever is chosen by the backend. If everything is set
|
||||||
@@ -34881,6 +34907,9 @@ v0.9.8 - 2019-xx-xx
|
|||||||
- Add support for controlling whether or not the content of the output buffer passed in to the data callback is pre-initialized
|
- Add support for controlling whether or not the content of the output buffer passed in to the data callback is pre-initialized
|
||||||
to zero. By default it will be initialized to zero, but this can be changed by setting noPreZeroedOutputBuffer in the device
|
to zero. By default it will be initialized to zero, but this can be changed by setting noPreZeroedOutputBuffer in the device
|
||||||
config. Setting noPreZeroedOutputBuffer to true will leave the contents undefined.
|
config. Setting noPreZeroedOutputBuffer to true will leave the contents undefined.
|
||||||
|
- Add support for clipping samples after the data callback has returned. This only applies when the playback sample format is
|
||||||
|
configured as ma_format_f32. If you are doing clipping yourself, you can disable this overhead by setting noClip to true in
|
||||||
|
the device config.
|
||||||
- Fix warnings emitted by GCC when `__inline__` is undefined or defined as nothing.
|
- Fix warnings emitted by GCC when `__inline__` is undefined or defined as nothing.
|
||||||
|
|
||||||
v0.9.7 - 2019-08-28
|
v0.9.7 - 2019-08-28
|
||||||
|
|||||||
Reference in New Issue
Block a user