Olav SørensenPushed v1.66 codef56d9f63 years agoHistory
2853 lines · 55.2 KB · C
RawDownload
#include <stdint.h>#include <stdbool.h>#include "ft2_mix.h"#include "ft2_mix_macros.h"#include "ft2_center_mix.h"#include "../ft2_cpu.h" /*** ------------ 32-bit floating-point audio channel mixer ------------**       (Note: Mixing macros can be found in ft2_mix_macros.h)**** Specifications:** - Interpolation: None, 2-tap linear, 8-tap windowed-sinc, 16-tap windowed-sinc** - FT2-styled linear volume ramping (can be turned off)** - 32.32 (16.16 if 32-bit CPU) fixed-point precision for resampling delta/position** - 32-bit floating-point precision for mixing and interpolation**** This file has separate routines for EVERY possible sampling variation:** Interpolation none/sinc/linear, volumeramp on/off, 8-bit, 16-bit, no loop, loop, bidi.** (36 mixing routines in total + another 36 for center-mixing)**** Every voice has a function pointer set to the according mixing routine on** sample trigger (from replayer, but set in audio thread), using a function** pointer look-up table. All voices & pointers are always thread-safely cleared** when changing any of the above attributes from the GUI, to prevent possible** thread-related issues.**** -----------------------------------------------------------------------------*/ /* ----------------------------------------------------------------------- *//*                          8-BIT MIXING ROUTINES                          *//* ----------------------------------------------------------------------- */ static void mix8bNoLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac; 	GET_VOL	GET_MIXER_VARS	SET_BASE8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP			INC_POS		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP			INC_POS			RENDER_8BIT_SMP			INC_POS			RENDER_8BIT_SMP			INC_POS			RENDER_8BIT_SMP			INC_POS		} 		HANDLE_SAMPLE_END	} 	SET_BACK_MIXER_POS} static void mix8bLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac; 	GET_VOL	GET_MIXER_VARS	SET_BASE8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP			INC_POS		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP			INC_POS			RENDER_8BIT_SMP			INC_POS			RENDER_8BIT_SMP			INC_POS			RENDER_8BIT_SMP			INC_POS		} 		WRAP_LOOP	} 	SET_BACK_MIXER_POS} static void mix8bBidiLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *revBase, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac, tmpDelta; 	GET_VOL	GET_MIXER_VARS	SET_BASE8_BIDI 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		START_BIDI		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP			INC_POS_BIDI		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP			INC_POS_BIDI			RENDER_8BIT_SMP			INC_POS_BIDI			RENDER_8BIT_SMP			INC_POS_BIDI			RENDER_8BIT_SMP			INC_POS_BIDI		}		END_BIDI 		WRAP_BIDI_LOOP	}	SET_BACK_MIXER_POS} static void mix8bNoLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac; 	GET_VOL	GET_MIXER_VARS	SET_BASE8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP_S8INTRP			INC_POS		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP_S8INTRP			INC_POS			RENDER_8BIT_SMP_S8INTRP			INC_POS			RENDER_8BIT_SMP_S8INTRP			INC_POS			RENDER_8BIT_SMP_S8INTRP			INC_POS		} 		HANDLE_SAMPLE_END	} 	SET_BACK_MIXER_POS} static void mix8bLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *smpPtr;	int8_t *smpTapPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac; 	GET_VOL	GET_MIXER_VARS	SET_BASE8	PREPARE_TAP_FIX8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once		{			for (i = 0; i < (samplesToMix & 3); i++)			{				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS			}			samplesToMix >>= 2;			for (i = 0; i < samplesToMix; i++)			{				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS			}		}		else		{			for (i = 0; i < (samplesToMix & 3); i++)			{				RENDER_8BIT_SMP_S8INTRP				INC_POS			}			samplesToMix >>= 2;			for (i = 0; i < samplesToMix; i++)			{				RENDER_8BIT_SMP_S8INTRP				INC_POS				RENDER_8BIT_SMP_S8INTRP				INC_POS				RENDER_8BIT_SMP_S8INTRP				INC_POS				RENDER_8BIT_SMP_S8INTRP				INC_POS			}		} 		WRAP_LOOP	} 	SET_BACK_MIXER_POS} static void mix8bBidiLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *revBase, *smpPtr;	int8_t *smpTapPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac, tmpDelta; 	GET_VOL	GET_MIXER_VARS	SET_BASE8_BIDI	PREPARE_TAP_FIX8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		START_BIDI		if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once		{			for (i = 0; i < (samplesToMix & 3); i++)			{				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS_BIDI			}			samplesToMix >>= 2;			for (i = 0; i < samplesToMix; i++)			{				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS_BIDI				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS_BIDI				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS_BIDI				RENDER_8BIT_SMP_S8INTRP_TAP_FIX				INC_POS_BIDI			}		}		else		{			for (i = 0; i < (samplesToMix & 3); i++)			{				RENDER_8BIT_SMP_S8INTRP				INC_POS_BIDI			}			samplesToMix >>= 2;			for (i = 0; i < samplesToMix; i++)			{				RENDER_8BIT_SMP_S8INTRP				INC_POS_BIDI				RENDER_8BIT_SMP_S8INTRP				INC_POS_BIDI				RENDER_8BIT_SMP_S8INTRP				INC_POS_BIDI				RENDER_8BIT_SMP_S8INTRP				INC_POS_BIDI			}		}		END_BIDI 		WRAP_BIDI_LOOP	} 	SET_BACK_MIXER_POS} static void mix8bNoLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac; 	GET_VOL	GET_MIXER_VARS	SET_BASE8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP_LINTRP			INC_POS		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP_LINTRP			INC_POS			RENDER_8BIT_SMP_LINTRP			INC_POS			RENDER_8BIT_SMP_LINTRP			INC_POS			RENDER_8BIT_SMP_LINTRP			INC_POS		} 		HANDLE_SAMPLE_END	} 	SET_BACK_MIXER_POS} static void mix8bLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac; 	GET_VOL	GET_MIXER_VARS	SET_BASE8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP_LINTRP			INC_POS		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP_LINTRP			INC_POS			RENDER_8BIT_SMP_LINTRP			INC_POS			RENDER_8BIT_SMP_LINTRP			INC_POS			RENDER_8BIT_SMP_LINTRP			INC_POS		} 		WRAP_LOOP	} 	SET_BACK_MIXER_POS} static void mix8bBidiLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *revBase, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac, tmpDelta; 	GET_VOL	GET_MIXER_VARS	SET_BASE8_BIDI 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		START_BIDI		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP_LINTRP			INC_POS_BIDI		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP_LINTRP			INC_POS_BIDI			RENDER_8BIT_SMP_LINTRP			INC_POS_BIDI			RENDER_8BIT_SMP_LINTRP			INC_POS_BIDI			RENDER_8BIT_SMP_LINTRP			INC_POS_BIDI		}		END_BIDI 		WRAP_BIDI_LOOP	} 	SET_BACK_MIXER_POS} static void mix8bNoLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples){	const int8_t *base, *smpPtr;	float fSample, *fMixBufferL, *fMixBufferR;	int32_t position;	uint32_t i, samplesToMix, samplesLeft;	uintCPUWord_t positionFrac; 	GET_VOL	GET_MIXER_VARS	SET_BASE8 	samplesLeft = numSamples;	while (samplesLeft > 0)	{		LIMIT_MIX_NUM		samplesLeft -= samplesToMix; 		for (i = 0; i < (samplesToMix & 3); i++)		{			RENDER_8BIT_SMP_S16INTRP			INC_POS		}		samplesToMix >>= 2;		for (i = 0; i < samplesToMix; i++)		{			RENDER_8BIT_SMP_S16INTRP			INC_POS			RENDER_8BIT_SMP_S16INTRP			INC_POS			RENDER_8BIT_SMP_S16INTRP			INC_POS			RENDER_8BIT_SMP_S16INTRP

Lines 1–500 of 2853.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t