mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-21 15:56:58 +02:00
Use ma_resampler instead of ma_linear_resampler for sound nodes.
This is infrastructure work for supporting custom resamplers for the pitching and Doppler effects for sounds. Public issue https://github.com/mackron/miniaudio/issues/965
This commit is contained in:
+16
-14
@@ -11166,7 +11166,7 @@ typedef struct
|
|||||||
ma_uint32 volumeSmoothTimeInPCMFrames;
|
ma_uint32 volumeSmoothTimeInPCMFrames;
|
||||||
ma_mono_expansion_mode monoExpansionMode;
|
ma_mono_expansion_mode monoExpansionMode;
|
||||||
ma_fader fader;
|
ma_fader fader;
|
||||||
ma_linear_resampler resampler; /* For pitch shift. */
|
ma_resampler resampler; /* For pitch shift. */
|
||||||
ma_spatializer spatializer;
|
ma_spatializer spatializer;
|
||||||
ma_panner panner;
|
ma_panner panner;
|
||||||
ma_gainer volumeGainer; /* This will only be used if volumeSmoothTimeInPCMFrames is > 0. */
|
ma_gainer volumeGainer; /* This will only be used if volumeSmoothTimeInPCMFrames is > 0. */
|
||||||
@@ -76581,7 +76581,7 @@ static void ma_engine_node_update_pitch_if_required(ma_engine_node* pEngineNode)
|
|||||||
|
|
||||||
if (isUpdateRequired) {
|
if (isUpdateRequired) {
|
||||||
float basePitch = (float)pEngineNode->sampleRate / ma_engine_get_sample_rate(pEngineNode->pEngine);
|
float basePitch = (float)pEngineNode->sampleRate / ma_engine_get_sample_rate(pEngineNode->pEngine);
|
||||||
ma_linear_resampler_set_rate_ratio(&pEngineNode->resampler, basePitch * pEngineNode->oldPitch * pEngineNode->oldDopplerPitch);
|
ma_resampler_set_rate_ratio(&pEngineNode->resampler, basePitch * pEngineNode->oldPitch * pEngineNode->oldDopplerPitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76741,7 +76741,7 @@ static void ma_engine_node_process_pcm_frames__general(ma_engine_node* pEngineNo
|
|||||||
ma_uint64 resampleFrameCountIn = framesAvailableIn;
|
ma_uint64 resampleFrameCountIn = framesAvailableIn;
|
||||||
ma_uint64 resampleFrameCountOut = framesAvailableOut;
|
ma_uint64 resampleFrameCountOut = framesAvailableOut;
|
||||||
|
|
||||||
ma_linear_resampler_process_pcm_frames(&pEngineNode->resampler, pRunningFramesIn, &resampleFrameCountIn, pWorkingBuffer, &resampleFrameCountOut);
|
ma_resampler_process_pcm_frames(&pEngineNode->resampler, pRunningFramesIn, &resampleFrameCountIn, pWorkingBuffer, &resampleFrameCountOut);
|
||||||
isWorkingBufferValid = MA_TRUE;
|
isWorkingBufferValid = MA_TRUE;
|
||||||
|
|
||||||
framesJustProcessedIn = (ma_uint32)resampleFrameCountIn;
|
framesJustProcessedIn = (ma_uint32)resampleFrameCountIn;
|
||||||
@@ -77056,9 +77056,10 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo
|
|||||||
ma_result result;
|
ma_result result;
|
||||||
size_t tempHeapSize;
|
size_t tempHeapSize;
|
||||||
ma_node_config baseNodeConfig;
|
ma_node_config baseNodeConfig;
|
||||||
ma_linear_resampler_config resamplerConfig;
|
ma_resampler_config resamplerConfig;
|
||||||
ma_spatializer_config spatializerConfig;
|
ma_spatializer_config spatializerConfig;
|
||||||
ma_gainer_config gainerConfig;
|
ma_gainer_config gainerConfig;
|
||||||
|
ma_uint32 sampleRate;
|
||||||
ma_uint32 channelsIn;
|
ma_uint32 channelsIn;
|
||||||
ma_uint32 channelsOut;
|
ma_uint32 channelsOut;
|
||||||
ma_channel defaultStereoChannelMap[2] = {MA_CHANNEL_SIDE_LEFT, MA_CHANNEL_SIDE_RIGHT}; /* <-- Consistent with the default channel map of a stereo listener. Means channel conversion can run on a fast path. */
|
ma_channel defaultStereoChannelMap[2] = {MA_CHANNEL_SIDE_LEFT, MA_CHANNEL_SIDE_RIGHT}; /* <-- Consistent with the default channel map of a stereo listener. Means channel conversion can run on a fast path. */
|
||||||
@@ -77077,6 +77078,7 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo
|
|||||||
|
|
||||||
pHeapLayout->sizeInBytes = 0;
|
pHeapLayout->sizeInBytes = 0;
|
||||||
|
|
||||||
|
sampleRate = (pConfig->sampleRate > 0) ? pConfig->sampleRate : ma_engine_get_sample_rate(pConfig->pEngine);
|
||||||
channelsIn = (pConfig->channelsIn != 0) ? pConfig->channelsIn : ma_engine_get_channels(pConfig->pEngine);
|
channelsIn = (pConfig->channelsIn != 0) ? pConfig->channelsIn : ma_engine_get_channels(pConfig->pEngine);
|
||||||
channelsOut = (pConfig->channelsOut != 0) ? pConfig->channelsOut : ma_engine_get_channels(pConfig->pEngine);
|
channelsOut = (pConfig->channelsOut != 0) ? pConfig->channelsOut : ma_engine_get_channels(pConfig->pEngine);
|
||||||
|
|
||||||
@@ -77096,10 +77098,10 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo
|
|||||||
|
|
||||||
|
|
||||||
/* Resmapler. */
|
/* Resmapler. */
|
||||||
resamplerConfig = ma_linear_resampler_config_init(ma_format_f32, channelsIn, 1, 1); /* Input and output sample rates don't affect the calculation of the heap size. */
|
resamplerConfig = ma_resampler_config_init(ma_format_f32, channelsIn, sampleRate, ma_engine_get_sample_rate(pConfig->pEngine), ma_resample_algorithm_linear);
|
||||||
resamplerConfig.lpfOrder = 0;
|
resamplerConfig.linear.lpfOrder = 0;
|
||||||
|
|
||||||
result = ma_linear_resampler_get_heap_size(&resamplerConfig, &tempHeapSize);
|
result = ma_resampler_get_heap_size(&resamplerConfig, &tempHeapSize);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return result; /* Failed to retrieve the size of the heap for the resampler. */
|
return result; /* Failed to retrieve the size of the heap for the resampler. */
|
||||||
}
|
}
|
||||||
@@ -77167,7 +77169,7 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p
|
|||||||
ma_result result;
|
ma_result result;
|
||||||
ma_engine_node_heap_layout heapLayout;
|
ma_engine_node_heap_layout heapLayout;
|
||||||
ma_node_config baseNodeConfig;
|
ma_node_config baseNodeConfig;
|
||||||
ma_linear_resampler_config resamplerConfig;
|
ma_resampler_config resamplerConfig;
|
||||||
ma_fader_config faderConfig;
|
ma_fader_config faderConfig;
|
||||||
ma_spatializer_config spatializerConfig;
|
ma_spatializer_config spatializerConfig;
|
||||||
ma_panner_config pannerConfig;
|
ma_panner_config pannerConfig;
|
||||||
@@ -77242,10 +77244,10 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* We'll always do resampling first. */
|
/* We'll always do resampling first. */
|
||||||
resamplerConfig = ma_linear_resampler_config_init(ma_format_f32, baseNodeConfig.pInputChannels[0], pEngineNode->sampleRate, ma_engine_get_sample_rate(pEngineNode->pEngine));
|
resamplerConfig = ma_resampler_config_init(ma_format_f32, baseNodeConfig.pInputChannels[0], pEngineNode->sampleRate, ma_engine_get_sample_rate(pEngineNode->pEngine), ma_resample_algorithm_linear);
|
||||||
resamplerConfig.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */
|
resamplerConfig.linear.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */
|
||||||
|
|
||||||
result = ma_linear_resampler_init_preallocated(&resamplerConfig, ma_offset_ptr(pHeap, heapLayout.resamplerOffset), &pEngineNode->resampler);
|
result = ma_resampler_init_preallocated(&resamplerConfig, ma_offset_ptr(pHeap, heapLayout.resamplerOffset), &pEngineNode->resampler);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
@@ -77304,7 +77306,7 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p
|
|||||||
|
|
||||||
/* No need for allocation callbacks here because we use a preallocated heap. */
|
/* No need for allocation callbacks here because we use a preallocated heap. */
|
||||||
error3: ma_spatializer_uninit(&pEngineNode->spatializer, NULL);
|
error3: ma_spatializer_uninit(&pEngineNode->spatializer, NULL);
|
||||||
error2: ma_linear_resampler_uninit(&pEngineNode->resampler, NULL);
|
error2: ma_resampler_uninit(&pEngineNode->resampler, NULL);
|
||||||
error1: ma_node_uninit(&pEngineNode->baseNode, NULL);
|
error1: ma_node_uninit(&pEngineNode->baseNode, NULL);
|
||||||
error0: return result;
|
error0: return result;
|
||||||
}
|
}
|
||||||
@@ -77353,7 +77355,7 @@ MA_API void ma_engine_node_uninit(ma_engine_node* pEngineNode, const ma_allocati
|
|||||||
}
|
}
|
||||||
|
|
||||||
ma_spatializer_uninit(&pEngineNode->spatializer, pAllocationCallbacks);
|
ma_spatializer_uninit(&pEngineNode->spatializer, pAllocationCallbacks);
|
||||||
ma_linear_resampler_uninit(&pEngineNode->resampler, pAllocationCallbacks);
|
ma_resampler_uninit(&pEngineNode->resampler, pAllocationCallbacks);
|
||||||
|
|
||||||
/* Free the heap last. */
|
/* Free the heap last. */
|
||||||
if (pEngineNode->_ownsHeap) {
|
if (pEngineNode->_ownsHeap) {
|
||||||
@@ -79407,7 +79409,7 @@ MA_API ma_result ma_sound_get_data_format(const ma_sound* pSound, ma_format* pFo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pSampleRate != NULL) {
|
if (pSampleRate != NULL) {
|
||||||
*pSampleRate = pSound->engineNode.resampler.config.sampleRateIn;
|
*pSampleRate = pSound->engineNode.resampler.sampleRateIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pChannelMap != NULL) {
|
if (pChannelMap != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user